6、采用Xpath 定位信息,下载贴吧第一页图片
6.1 爬虫的一般思路
- 分析目标网页,确定爬取的url路径,headers参数【静态网页还是动态网页】
- 发送请求 --requests 模拟浏览器发送请求,获取响应数据
- 解析数据 --parsel 转化为selector对象,selector对象只有xpath的方法,能够对转化的数据
- 保存数据
6.2 贴吧图片下载分析
- 如何下载一个图片?
- 如何下载一个网页中的图片?
- 如何循环下载多个网页中的图片?
6.3 源代码
6.3.1 判断是否为静态网页
6.3.2 伪造请求头
import requests
import parsel
右击,点击检查F12--->network---->刷新页面,所有的数据包,随意点击数据包,定位headers【user_agent是浏览器的身份标识,不同的user_agent有不同的标识】
# 伪造请求头
headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'}
6.3.3 模拟浏览器发送请求
# 2.模拟浏览器发送请求
base_url='https://tieba.baidu.com/f?ie=utf-8&kw=%E7%A7%91%E6%8A%80&fr=search' # 静态网页进行地址导航栏的url [中文字符变为%E7%BE%8E%E5%A5%B3%E5%90%A7&进行了加密]
response =requests.get(base_url,headers=headers) # 模拟浏览器请求url,response对象
html_str=response.text # 取出对象的文本【html的字符串】
print(html_str) # 可以在代码编程框中进行检查 【ctrl+f
print(response) # 判断浏览器访问是否成功【结果为200或202为成功】
"""
问题:爬取好网页HTML信息后,进一步利用xpath爬取站内需要的链接时,返回结果一直是空列表。
原因:准备爬取的数据全是被注释了的
解决:html_new=html.replace(r'<!--','"').replace(r'-->','"') 利用正则把源代码里的注释符修改,起不到注释的作用
"""
html_str=html_str1.replace(r'<!--','"').replace(r'-->','"')
6.3.4 解析数据【每个帖子的链接--->每个图片的链接】
parsel模块的作用:主要用来将请求后的字符串格式解析成re、xpath、css进行内容的匹配。对象为Selector()。
Xpath使用链接:https://blog.csdn.net/ab19920904/article/details/107390193
# parsel使用方法
import requests
import parsel
response=requests.get(url)
sel=parsel.Selector(response.text) # 注意这里的S要大写
# re正则
# print(sel.re('正则匹配格式'))
# xpath
# print(sel.xpath('xpath').getall()) #getall获取所有
# css选择器
# print(sel.css('css选择器::text').extract_first()) #获取第一个
'''
3.1 得到每个帖子的末位链接
'''
html=parsel.Selector(html_str) #--parsel 转化为selector对象,selector对象只有xpath的方法,能够对转化的数据
# 提取数据
title_url=html.xpath('//div[@class="threadlist_lz clearfix"]/div/a/@href').extract()# 提取每个帖子的链接,返回是select对象
print(title_url) # 得到href的属性值 帖子的id
'''
3.2 拼接完整的帖子的url链接
'''
second_url='https://tieba.baidu.com'
for url in title_url:
all_url=second_url+url
print('当前帖子的链接为:',all_url)
"""
3.3 得到每个帖子中图片的链接
"""
# 发送每个帖子的链接请求
response_2=requests.get(all_url,headers=headers).text #第二次响应
# 解析图片的链接
response_2_data=parsel.Selector(response_2)
result_list=response_2_data.xpath('//cc/div/img[@class="BDE_Image"]/@src').extract()
# print(result_list)
# 发送图片地址的请求
for li in result_list: #循环的请求每一张图片
img_data=requests.get(li,headers=headers).content # 图片是二进制数据,通过content函数获取图片数据
'''
3.4 保存数据【图片文件名;图片【链接的后半段.jpg作为文件名】】
'''
# 文件名
file_name=li.split('/')[-1] # 取最后一段作为图片名称
print('正在下载图片',file_name)
with open(r'D:\\img\\'+file_name,'wb') as f: # 双斜杠【表示转义】 f是别名为空【f指代with open('img\\'+file_name,'wo')】
# 1、文件夹+文件名;2、文件写入方式【图片的格式二进制,所以用wb进行写入】
f.write(img_data)
6.3.5 实现循环抓取
规律:通过pn的变化进行翻页,是按50递增的。
page_num=0
for page in range(0,2020550+1,50): #+1的作用range是左闭右开的[0,2020550),因此+1就包含了2020550
page_num+=1
print('=====正在抓取第{}页的数据======'.format(page_num))
base_url='https://tieba.baidu.com/f?kw=%E7%BE%8E%E5%A5%B3&ie=utf-8&pn={}'.format(page) #{}预留一个接口