一.requests的使用
在上篇文章中给大家演示了一下使用urllib模块中的request爬取豆瓣电影, 相信大家练习过后都会觉得很简单, 今天带大家开始使用requests模块了, 关于requests的介绍与安装在上篇文章中已经有过描述, 这里就不再赘述了.
-
requests的get请求:
import requests url = '...' # 定制请求头 headers = { "User-Agent":'...' } response = requests.get(url=url, headers=headers)
定制请求头: 在访问大多数网站时, 如果使用脚本或者程度爬取页面, 必需要进行UA伪装, 如下图
UA我们可以打开浏览器进行抓包, 直接复制粘贴, 或者随机生成UA, 在后面文章中会提到
-
get请求 + params
import requests url = '...' # 定制请求头 headers = { "User-Agent":'...' } # 参数 params = { 'key': 'value' } response = requests.get(url=url, headers=headers, params=params)
什么情况下使用params?
在你抓包时的请求头中有如上类似的参数时就可以使用params -
requests.get + headers + params + proxies
import requests url = '...' # 定制请求头 headers = { "User-Agent":'...' } # 参数 params = { 'key': 'value' } # 代理IP proxies = { # 发送的请求为http请求 'http': 'http://127.0.0.1:8080' # 发送的请求为https请求 'https': 'http://127.0.0.1:8899' }
当你需要大量爬取网页数据而又要避免被IP封禁的时候就可能会用到代理IP, 列举两个好用的代理IP平台, 大家可以去尝试
- 快代理
- 西刺代理
代理分为三种: 透明代理、匿名代理、高匿代理, 推荐大家都使用高匿代理的IP
二.xpath解析库的安装与使用
网页由三部分组成: HTML, Css, JavaScript, HTML页面标签存在层级关系, 即DOM树, 在获取目标数据时可以根据网页层次关系定位标签, 在获取标签的文本或属性.
xpath解析库解析数据原理:
1. 根据网页DOM树定位节点标签
2. 获取节点标签的征文文本与属性值
xpath的安装与使用:
xpath安装: pip install lxml
常用规则:
1. nodename: 节点名定位
2. //: 从当前节点选取子孙节点
3. /: 从当前节点选取直接子节点
4. nodename[@attribute="…"] 根据属性定位标签
5. @attributename: 获取属性值
6. text(): 获取文本
属性匹配两种情况: 多属性匹配 & 单属性多值匹配
- 多属性匹配
from lxml import etree tree = etree.HTML(response.text) # 有一个class属性和name属性 tree.xpath('//div[@class="item" and @name="test"]/text()')
- 单属性多值匹配
from lxml import etree tree = etree.HTML(response.text) # 在class这个属性中可能包含有多个值, 只取其中一个 tree.xpath('//div[contains(@class, "dc")]/text()')
按序选择
- 索引定位
from lxml import etree tree = etree.HTML(response.text) # 需要注意: 匹配中索引是从1开始的 index_order = tree.xpath('//div[@class="c1"][1]/text()')
- last()函数
from lxml import etree tree = etree.HTML(response.text) # last默认只取最后一个 last_order = tree.xpath('//div[@class="c1"][last()]/text()') # 也可以这样 last_order = tree.xpath('//div[@class="c1"][last()-1]/text()')
- position()函数
from lxml import etree tree = etree.HTML(response.text) # position()可以写表达式 position_order = tree.xpath('//div[@class="c1"][position()<2]/text()')
三.分析页面, 制定爬虫流程
1.对糗百页面进行分页抓包, 查找分页规律
2.检查数据的来源(静态or动态)
3.确认url
4.代码模拟请求爬取数据
四.使用requests爬取网站
这次带大家使用requests爬取糗事百科热门网站
from lxml import etree
import requests
import json
# 定义写入文件的路径
FML_PATH = 'qiu_bai.json'
# 拼接图片的路径
IMAGE_PATH = 'https://www.qiushibaike.com'
# 定义全局变量, 用于存储数据
ret_list = []
def qiu_bai(page):
"""
爬取糗事百科热门前两页的每一项标题、详情页连接
"""
url = 'https://www.qiushibaike.com/8hr/page/%s/' % page
# 定制请求头信息
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
"Chrome/74.0.3729.108 Safari/537.36",
}
# 根据get请求方式获取响应
response = requests.get(url=url, headers=headers)
# 根据响应结果来实例化etree解析对象
tree = etree.HTML(response.text)
# 使用xpath解析页面
li_list = tree.xpath('//div[@class="recommend-article"]/ul/li')
# 函数内修改全局变量需要使用global声明
global ret_list
for li in li_list:
# 定义一个空的字典
ret_dict = dict()
# 对获取到的li再次解析拿到标题
title = li.xpath('./div/a/text()')[0]
# 对获取到的li再次解析拿到详情页路径
path = IMAGE_PATH + li.xpath('./div/a/@href')[0]
# 添加到字典中
ret_dict['title'] = title
ret_dict['path'] = path
# 将字典添加到全局变量列表中
ret_list.append(ret_dict)
if __name__ == '__main__':
for i in range(1, 3):
qiu_bai(i)
# 爬取数据完毕, 将列表数据写入文件内
json.dump(ret_list, open(FML_PATH, 'w', encoding='utf-8'), ensure_ascii=False, indent=4)
五.总结
xpath解析库的使用我个人认为还是非常好用的, 希望大家在爬取网页前, 先对xpath的语法进行练习, 以免在解析过程中出现不必要的问题, 还要注意的是, 一定一定一定要先制定好爬虫的大概流程再进行页面爬取.