##Python爬取站长素材上的图片
罗纳尔康
首先这是一个学习的案例,我将其记录下来,因为所学的内容有点多,爬取这个图片,我是用的xpath来解析网页,当然也可以用bs4来进行解析,看个人喜好,该案例比较简单,但涉及的内容并不少。
1.分析每页的url地址栏
第一页:https://sc.chinaz.com/tupian/gougoutupian.html
第二页:https://sc.chinaz.com/tupian/gougoutupian_2.html
第三页:https://sc.chinaz.com/tupian/gougoutupian_3.html
可以看出来除了第一页以外,后面的每一页都是_页码,下划线+页码。所以这个规律很好找,就除了第一页以外,之后的每一页都拼接一个下划线+页码就可以完成url地址栏的获取。
2.定制请求对象
首先需要 定制请求对象需要的两个参数,一个是URL地址,一个headers,请求头。
因此第一步定义一个定制请求对象的函数,并且是一个含参有返回值的函数,参数用于接收传来的页码,并将得到的请求对象返回过去,用于下一步的获取内容。
首先就是url,url用if判断,除了第一页直接给https://sc.chinaz.com/tupian/gougoutupian.html这个地址以外,后面的每一页都是
url=‘https://sc.chinaz.com/tupian/gougoutupian_’+str(page)+’.html’,用来改变url地址,从而获取不同页的数据。
headers:可在浏览器中的开发者模式中去复制,并且是一个字典类型。
![在这里插入图片描述](https://img-blog.csdnimg.cn/ea1627dc2a964e089622217ef4c04a8c.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA572X57qz5bCU5bq3,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
将url和headers两个参数传入urllib.request.Request()这个方法中,将会得到一个request。将这个请求对象返回,下一步将会用到。
def create_request(page):
if(page==1):
url='https://sc.chinaz.com/tupian/gougoutupian.html'
else:
url='https://sc.chinaz.com/tupian/gougoutupian_'+str(page)+'.html'
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'
}
request=urllib.request.Request(url=url,headers=headers)
return request
3.获取响应内容
一样定义一个函数用于获取响应内容,封装起来。
通过urllib.request.urlopen(request)方法可以获取响应的respone,将其读取出来,respone.read().decode(‘utf-8’),注意编码格式,要和获取的一致,基本都是utf-8。这样就得到了网页的源码,具体需要的内容,通过下一步的xpath来筛选自己所需的内容。
def get_content(request):
respone=urllib.request.urlopen(request)
content=respone.read().decode('utf-8')
return content
4.下载图片内容
为了将获取到的内容筛选下载下来,需要引入xpath库。
接下来就是解析数据,我们需要下载图片,先来分析下网页的内容。
![在这里插入图片描述](https://img-blog.csdnimg.cn/ab7a3e8bbb3b4e13853660a69322b40b.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA572X57qz5bCU5bq3,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
所以我们获取先获取图片的名称,xpath为//*[@id=“container”]/div/div/a/img/@alt,将会返回一个列表名称
下面就是图片的链接地址,其中涉及到一个图片的懒加载。//*[@id=“container”]/div/div/a/img/@src2
![在这里插入图片描述](https://img-blog.csdnimg.cn/b4edd0852d7645b496a94cac7b3c4784.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA572X57qz5bCU5bq3,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
就可以获取到它们的一个名字列表和下载地址列表。可是下载地址是https:,所以应该拼接起来。
![在这里插入图片描述](https://img-blog.csdnimg.cn/1b5474921ab04577ad74eebe9193cf43.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA572X57qz5bCU5bq3,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
然后最后用urllib.request.urlretrieve(url,filename),第一个参数传下载的地址,第二个则是文件的名字。
效果图如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/a36eb45827b249d7b3b8c1db353cd1b4.gif#pic_center)
最后完整的代码如下
#需求:爬取站长素材上的狗狗图片的前5页数据
#第一页
#https://sc.chinaz.com/tupian/gougoutupian.html
#第二页
#https://sc.chinaz.com/tupian/gougoutupian_2.html
#第三页
#https://sc.chinaz.com/tupian/gougoutupian_3.html
import urllib.request
from lxml import etree
#1.定制请求对象
def create_request(page):
if(page==1):
url='https://sc.chinaz.com/tupian/gougoutupian.html'
else:
url='https://sc.chinaz.com/tupian/gougoutupian_'+str(page)+'.html'
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'
}
request=urllib.request.Request(url=url,headers=headers)
return request
#2.获取内容
def get_content(request):
respone=urllib.request.urlopen(request)
content=respone.read().decode('utf-8')
return content
#3.下载图片
def down_load(content):
#将获取的内容,传进去用于解析数据
tree=etree.HTML(content)
#xpath解析数据,首先解析一下图片的名称,在解析图片的地址
name_list=tree.xpath('//*[@id="container"]/div/div/a/img/@alt')
src_list=tree.xpath('//*[@id="container"]/div/div/a/img/@src2')
for i in range(len(name_list)):
name=name_list[i]
src=src_list[i]
url='https:'+src
urllib.request.urlretrieve(url=url,filename='./狗狗图片/'+name+'.jpg')
if __name__ == '__main__':
start_page=int(input('请输入起始页'))
end_page=int(input('请输入结束页'))
#循环遍历页数
for page in range(start_page,end_page+1):
#定制请求对象
request=create_request(page)
#获取响应内容
content=get_content(request)
#批量下载图片
down_load(content)