结合Selenium 和 Requests完成动态数据爬取

Selenium
简介
Selenium是一个用于Web应用程序测试的工具。Selenium测试直接调用操作浏览器,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本。

简言之,Selenium提供一套API,包含了元素定位、模拟操作(点击、输入…)等功能。在运行时会启动一个处于调试状态下的浏览器。需要注意的是,启动相应的浏览器需要对应的驱动。下载完成后可以将驱动放置在环境变量包含的路径中,或是在代码中指定路径。

# 使用项目的相对路径
chrome = webdriver.WebDriver(executable_path='./Driver/chromedriver_80.exe')
1
2
安装
以python为例:

pip install selenium
1
Requests
Requests: HTTP for Humans™

简介
Requests是一个非常好用的Python的HTTP库,通过Requests我们可以向服务器发起GET、POST等请求。Requests也提供了对会话的支持。

安装
pip install requests
1
静态页面与动态页面
静态页面是用户发起请求后,在服务器端直接生成最终页面,并发送回客户端,客户端直接进行加载渲染即可。
动态页面往往在用户发起请求后,服务器仅仅返回数据部分,客户端接收到数据后,再将数据填充进页面中,进行渲染。

动态页面占用服务器资源少,以一个搜索任务为例,服务器仅仅是完成一个数据库查询后,将数据以特定格式返回给客户端;静态页面则要求服务器完成查询后,还需要将整个页面“拼接”出来,再发送返回给客户端。

静态页面的爬虫相对容易完成,因为所有的元素都能在HTML源码中找到,我们使用相应的工具便可以快速定位元素路径,进行数据爬取,也就是说,对于静态页面,我们拿到页面便拿到了数据。静态页面可以直接通过Requests库来访问链接进行获取。

动态页面在页面解析时相对复杂麻烦一点,因为我们从浏览器看见的是通过js渲染完成后的界面,页面源码并不是最终产物,在进行元素定位时,因为页面的动态性,页面源码是随着用户操作而发生改变的,所以盲目使用元素定位往往结果难以令人满意,而且容易丢失元素。如果直接通过Requests库进行获取,获取到的页面仅仅是一个框架,是js还没有执行过的页面。

动态页面爬取的两种思路
既然我们直接进行获取的页面是没有执行js进行渲染过的界面,那么我们可以尝试先对其调用js渲染,再获取其页面。(想方法获取到最终页面)
模拟浏览器,直接向服务器发起请求,获取服务器返回数据。(直接收集数据)
这里着重讲解第二种方法。

如何模拟浏览器
构造请求
请求是什么
我们发起的每一个请求,都携带了额外的信息,当我们想方设法将这些信息都通过代码加入到我们的请求中时,我们就完美模拟了浏览器。这些信息组成了请求头和请求体。请求头,用来说明服务器要使用的附加信息,请求体一般承载的内容是 POST 请求中的表单数据(Payload),而对于 GET 请求,请求体则为空。

请求头中常见的信息有Cookie、Referer、User-Agent等。

User-Agent
简称 UA,它是一个特殊的字符串头,可以使服务器识别客户使用的操作系统及版本、浏览器及版本等信息。在做爬虫时加上此信息,可以伪装为浏览器;如果不加,很可能会被识别出为爬虫。

Cookie
也常用复数形式 Cookies,这是网站为了辨别用户进行会话跟踪而存储在用户本地的数据。它的主要功能是维持当前访问会话。例如,我们输入用户名和密码成功登录某个网站后,服务器会用会话保存登录状态信息,后面我们每次刷新或请求该站点的其他页面时,会发现都是登录状态,这就是 Cookies 的功劳。Cookies 里有信息标识了我们所对应的服务器的会话,每次浏览器在请求该站点的页面时,都会在请求头中加上 Cookies 并将其发送给服务器,服务器通过 Cookies 识别出是我们自己,并且查出当前状态是登录状态,所以返回结果就是登录之后才能看到的网页内容。

Cookie好比是游乐园里盖在手背上的章,有了这个章才可以进去玩。每一次进出的时候,只需要给管理员看一下你的章,管理员就知道你是买过票的,就不需要再一次购买。

Referer
此内容用来标识这个请求是从哪个页面发过来的,服务器可以拿到这一信息并做相应的处理,如做来源统计、防盗链处理等。

Payload
Payload是表单数据,可能是我们搜索的关键字,也可能包含我们的筛选条件。

如何构造请求
幸运的是,Requests库本身已经为我们提供了构造请求的方法,我们只需要拿到数据并填充即可。

Cookies
Cookies在需要登录的情况下有用,当我们通过Selenium打开网址完成登录后,可以通过Selenium获取到Cookies,以下代码实现一个简单的示例。

# 实例化一个浏览器
chrome = webdriver.WebDriver(executable_path='Driver/chromedriver_80.exe', options=option)

# 打开一个网页,以bilibili登录页面为例
# 在浏览器中输入账号与密码,当然也可以通过代码实现查找对应输入框输入文本
chrome.get("https://passport.bilibili.com/login")

# 构造“会话”
sess = requests.Session()
# 获取cookies
cookies = chrome.get_cookies()
# 填充
for cookie in cookies:
    sess.cookies.set(cookie['name'], cookie['value'])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
请求其余信息
获取请求内容最准确的方法是直接从浏览器的开发者工具中进行拷贝。可以先通过浏览器进行一次手动请求,即可从浏览器的开发者工具中看见请求的详细信息。

首先打开开发者工具,以Chrome为例,快捷键Ctrl + Shift + I即可。
设置过滤器为XHR。
点击按钮(查询、提交等,即你发起请求需要点击的那个按钮)。
在开发者工具下面出现的响应中找到你需要的那一条记录。
复制信息到代码中。
浏览器访问的url和请求方法。

请求头
请求体
下面展示一个较为完整的代码。
import requests
import json 
from selenium.webdriver.chrome import webdriver

# 实例化一个浏览器
chrome = webdriver.WebDriver(executable_path='Driver/chromedriver_80.exe', options=option)

# 打开一个网页,以bilibili登录页面为例
# 在浏览器中输入账号与密码,当然也可以通过代码实现查找对应输入框输入文本
chrome.get("https://passport.bilibili.com/login")

# 构造“会话”
sess = requests.Session()

sess.headers.clear()
# 依照实际情况一一复制
# 此处略有省略
sess.headers.setdefault('Accept', 'application/json, text/javascript, */*; q=0.01')
sess.headers.setdefault('Accept-Encoding', 'gzip, deflate, br')
sess.headers.setdefault('Accept-Language', 'en-US,en;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6')
sess.headers.setdefault('Content-Length', '3293')
sess.headers.setdefault('Content-Type', 'application/json')
sess.headers.setdefault('Origin', 'https://www.bilibili.com')
sess.headers.setdefault('Referer', 'https://www.bilibili.com/v/douga/?spm_id_from=333.5.b_70______________________56c4d656e75.1')
sess.headers.setdefault('User-Agent','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36')


# 获取cookies
cookies = chrome.get_cookies()
# 填充cookies
for cookie in cookies:
    sess.cookies.set(cookie['name'], cookie['value'])

# 直接将浏览器开发者工具中显示的Requests Payload复制下来,然后包成一个字符串
payload = '{"uploads":[{"src_id":154,"ad_server":"bilibili","is_ad":1,"area":1,"ad_cb":"CPraDRCfuk4Y3tjgHyCPBygBMPIyOJoBQh8SNS0mLWjLlIG57u16ZizWgblm5vlt51iBuS4luZWQscGxheXBhZ2VjdHI6ZW5hYmxlX25vX2VjcG1fdGhyZXNob2xkLG5vX2FkX2Zsb3dfY29udHJvbDp1bmRlZmluZWQsYnJ1c2h……'

url = 'https://cm.bilibili.com/cm/api/fees/pc'
response = sess.post(url, data=payload)
json_data = response.text
json_data = json.loads(json_data)
————————————————
版权声明:本文为CSDN博主「程序猿D」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/JunhuanPeng/article/details/105903626

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值