以一个例子作为开头
从大师网站自动下载项目的高清图片
参考链接:https://mp.weixin.qq.com/s/pqFR4TigBCS--barsfuz1A
这个程序写的有点东西,而且这个例子说实话是有点偏难的,因为已经用到了一些爬虫相关的知识点,这也是自己没能掌握的,不过这些东西都是自己后面会掌握的一部分,所以也没啥好说的。
没有使用Selenium,采用纯代码的方式,省下浏览器打开图片渲染页面的时间消耗
具体的步骤如下:
- 访问网站
- 找到有哪些项目,以及项目的详细介绍网页
- 在项目的详细介绍网页中找到高清大图的地址
- 下载图片
# 导入requests:是python实现的简单易用的HTTP库
# 导入re库:re库是python的标准库,主要用于字符串匹配
import requests, re, os
# Beautifulsoup包:用python写的一个HTML/XML的解析器,可以很好的处理不规则标记并生成剖析树(parse tres),他提供了简单又常用的导航(navigating),搜索以及修改剖析树的操作,大大节省编程的时间。
# 使用from bs4 import BeautifulSoup直接将BeautifulSoup类导入到当前命名空间,直接使用,不需要再带包名
from bs4 import BeautifulSoup
# 输入大师的网址,这里的r是转义符,即raw string,会自动的将反斜杠进行相应的转义
project_url = r'https://calatrava.com/projects.html?all=yes'
# 访问网站的模块,以后需要访问网站的时候都会用到这个函数
def download_page(url):
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'
}
data = requests.get(url, headers=headers).content.decode('utf-8')
return data
#####从页面的html语言中解析出项目地址
# 解析得到标题与项目地址的列表
# 拆分出:1.每个项目的信息
def parse_html(url):
html = download_page(url)
soup = BeautifulSoup(html, features='lxml')
project_list_part=soup.find("div",{"class":"mod_cal_project_list thumb_view block"})
project_list_soup = project_list_part.find_all('li', {'class': {'odd',"even"}})
return project_list_soup
# 在项目信息中提取项目的名称,得到一个列表
def get_project_title(project_list_soup):
project_title = []
for link in project_list_soup:
project_year = link.find('span', {'class': 'year'})
links = link.find('a')['href']
name = str(project_year.string) + '--'+ str(links[9:-5])
project_title.append(name)
return project_title
# 解析出每个项目的地址,得到一个列表
def get_project_link(project_list_soup):
project_link = []
for link in project_list_soup:
links = link.find('a')['href']
#因为项目的详细页面的默认状态是看文字介绍,所以还需要在后面加入一个进入画廊状态的字符串
links = str(r"https://calatrava.com/" + links+r"?view_mode=gallery")
project_link.append(links)
return project_link
### 在项目详细介绍的网页找到高清大图的地址(解析出隐藏在翻页动画背后的高清大图的存储结构)
### 页面的动画效果是通过一个JavaScript代码实现的,每个项目的大图都是结构化的存储在这段json对象中,直接用正则表达式提取出来就可以
# 解析项目子项页面,得到图片地址的列表
def parse_sub_html(project_link):
html = download_page(project_link)
project_soup = BeautifulSoup(html, features='lxml')
# 抓取JavaScript代码,解析出图片存放的实际地址
project_img_links_script=project_soup.find_all("script")
project_img_links=re.findall(r"'(?P<addr>files.*)', title",str(project_img_links_script))
for i in range(len(project_img_links)):
project_img_links[i]=str(r"https://calatrava.com/")+project_img_links[i]
# print(str(project_img_links_script))
print(project_img_links)
print("此项目大图数量 = "+"len(project_img_links")
return project_img_links
# 根据图片地址的列表,设定命名规则,保存图片
def save_img(links, name):
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'}
os.makedirs('./Calatrava project img/', exist_ok=True)
t = 1
for link in links:
filename = str('./Calatrava project img/' + str(name) + '%s.jpg' % (repr(t)))
print("Downloading----",str(filename))
with open(filename, "wb") as img:
img.write(requests.get(link, headers=headers).content)
t += 1
# 组装成一个main函数运行就可以进行后面的收图工作
def main():
soup = parse_html(project_url)
# 得到项目名称以及项目地址
name = get_project_title(soup)
link = get_project_link(soup)
print(link)
# 进入项目子项地址下载图片
# 引入项目代号t可以从第t个项目开始下载,以防网络错误
t = 0
while t < len(name):
# 考虑空项目地址引起download函数报错
if link[t] == "":
print("Skip it,Because it is null,Hurry coding,,Fix it later")
t += 1
else:
img_list = parse_sub_html(link[t])
print('Project Name is :', name[t])
save_name = str(repr(t + 1)+"-" + name[t])
save_img(img_list, save_name)
print('No %s is ok' % repr(t + 1))
t += 1
if __name__ == '__main__':
main()