Python爬虫案例与实战:爬取源代码练习评测结果
本章案例将介绍用 Python编写程序实现简单网站的模拟登录,然后保持登录后的网页会话,并在会话中模拟网页表单提交,之后使用 Requests库的高级特性爬取提交之后的返回结果。在HTTP网页中,如登录、提交和上传等操作一般通过向网页发送请求实现。通过对网页抓包分析,判断请求操作的类型,进而用Python的Requests库构建一个网页请求,模拟实际的网页提交。
4.1网站分析
POJ是老牌的供ACM/ICPC(大学生程序设计竞赛)选手在线提交程序源代码进行评测的练习平台,提交代码后需要跳转至网站的评测状态页面,再寻找用户所提交代码的评测结果。由于这种操作相对麻烦,本案例将通过编写模拟登录网站,并且通过表单提交的方式,上传评测用代码,提交之后发送请求,获取评测结果输出。
为分析登录的请求方式,在登录界面,务必在输入账号密码前,打开浏览器的开发者模式,找到Net Work 选项。再登录,此时开发者模式下会显示登录后的各种请求,找到login项,如图4-1所示,容易分析得出登录时的请求方式是POST请求。
页面往下拉,登录时 POST请求的内容如图4-2所示。可以看到 POST 发送的内容,有4个参数,前两个是用户的I和密码,后两个参数固定。需注意在编写爬虫程序时,POST内容的参数值是多少。
因为只看POST请求返回结果并不能判断是否登录成功,需要分析网页验证是否登录成功。其中一种常见的验证方法是访问代码提交界面。如果未登录成功,则会弹出登录框提示登录,如图4-3所示。如果登录成功,则通过网页元素分析,查看用于POST请求的form(表格)处的操作是login(登录)还是submit(提交),如图4-4所示。对比分析得出登录状态不同时HTML 文本的不同。
与登录成功时的操作相似,想要分析代码提交页面,必须提前打开开发者界面,单击“提交”按钮后抓包,如图4-5所示。在代码提交POST 请求的内容中,参数分别代表题目ID、提交所用语言(在可选语言列表中选择相应的下标,如4代表 C++语言、5代表C语言)、源代码和固定参数。注意,源代码提交方式采用 base64编码,属于HTTP网页中常见的表单提交方式和内容加密方式。
最后,是获取评测结果,在实际中,POJ的评测量很大,公屏评测结果刷新很快,只能通过手动输入用户ID的方式查看特定用户的评测结果,评测结果显示界面的URL 的格式为“poj.org/status?problem_id=&.user_id=&.result=&.language=”,看出是采用 GET 方式请求结果,如图4-6所示。通过分析网页元素,可以发现一条评测结果位于HTML 文本节点的子节点,此时想要获取最新结果,只需要访问第一个子节点,再遍历其子节点获取具体评测结果。
4.2编写爬虫
按以上分析网页和操作的思路,可以编写爬虫,具体操作如下。
(1)main()函数部分用于创建访问会话,并将验证登录,提交代码。注意,将获取评测结果的函数的接口放在 main()函数中。
if __name__ == '__main__':
user_name = 'ajshederay00616'
logindata = {
'user_id1': 'ajshederay00616',
'password1': '114514yjsnpi', 'B1': 'login', 'url': '%2F'}
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Safari/537.36'}
session = requests.session()
login_req = session.post('http://poj.org/login',
data