您好,欢迎访问代理记账网站
  • 价格透明
  • 信息保密
  • 进度掌控
  • 售后无忧

10.穿越网页表单与登录窗口进行抓取

之前和之后的网络爬虫在和 Web 服务器进行数据交互时,基本都是用 HTTP协议的 GET 方法去请求信息。POST方法,即把信息推送到 Web服务器进行存储和分析。就像网站的链接标记可以帮助用户发出 GET 请求一样,HTML 表单可以帮助用户发出 POST 请求。
1.Python Requests库
Requests 库就是一个擅长处理复杂的 HTTP 请求、cookie、header(响应头和请求头)等内容的 Python 第三方库。
和任何 Python 第三方库一样,Requests 库也可以用其他第三方 Python 库管理器(比如 pip)安装,或者直接下载源代码安装。
2.提交一个基本表单
大多数网页表单都是由一些 HTML 字段、一个提交按钮和一个进行表单处理的操作页面构成的。虽然这些 HTML 字段通常由文字内容构成,但是也可以实现文件上传或包含其他非文字内容。
大多数主流网站都会在它们的 robots.txt 文件里注明禁止爬虫接入登录表单(抓取这类表单可能需要承担相关法律责任)
pythonscraping.com网站为书本作者为读者学习爬虫创建的。其中一个简单的表单文件如下:

<form method="post" action="processing.php">
First name: <input type="text" name="firstname"><br>
Last name: <input type="text" name="lastname"><br>
<input type="submit" value="Submit">
</from>

字段的名称决定了表单提交后要被 POST 到服务器上的可变参数的名称。若模拟表单提交数据的行为,就要保证你的变量名称与字段名称是一一对应的。
表单的操作发生在action字段中processing.php文件(此处为相对文件路径),对表单的任何 POST 请求其实都发生在这个页面上,而非表单本身所在的页面。切记:HTML 表单的目的,只是帮助网站的访问者将格式正确的请求发送到进行实际操作的页面。
用Requests库提交这个表单,代码如下:

import requests

params = {'firstname': 'Ryan', 'lastname': 'Mitchell'}
r = requests.post("http://pythonscraping.com/pages/processing.php", data=params)
print(r.text)

在这里插入图片描述
有些表单的源码比较复杂,但是在大多情况下只需关注两件事:

  • 你想提交数据的字段的名称(上面代码中是Fistname和Lastname)
  • 表单的 action 属性,也就是表单提交后网站会显示的页面

3.单选按钮、复选框和其他输入
并非所有的网页表单都只是一堆文本字段和一个提交按钮。HTML 标准里提供了大量可用的表单输入字段:单选按钮、复选框和下拉选框等。HTML5 还增加了其他的控件,比如滚动条(范围输入字段)、邮箱、日期等。自定义的 JavaScript 字段能实现开发者能想到的任何功能。

表单的字段看起来多么复杂,仍然只有两件事是需要关注的:字段名称和字段值。字段名称可以通过查看源代码并寻找 name 属性轻易获得。而字段的值有时会比较复杂,因为它有可能是在表单提交之前通过 JavaScript 生成的。取色器就是一个比较奇怪的表单字段,它可能会用类似 #F03030 这样的值。

不确定输入字段值的数据格式,有一些工具可以跟踪浏览器和网站之间来回发送的 GET 和 POST 请求。

  • 跟踪 GET 请求最显而易见的方式就是看网站的 URL 链接。例如http://domainname.com?thing1=foo&thing2=bar可以知道字段名称和字段值。
  • 如果是很复杂的POST表单,想查看浏览器向服务器传递了哪些参数,最简单的方法就是用浏览器的检查器(inspector)或开发者工具查看。例如Chrome的F12,它提供了浏览器与网站交互时产生的所有请求,是一种详细查看请求参数的好方法。例如Network查看头部信息。

4.提交文件和图像
http://pythonscraping.com/files/form2.html为文件上传表单,源代码如下:

<form action="processing2.php" method="post" enctype="multipart/form-data">
	Submit a jpg, png, or gif: <input type="file" name="uploadFile"><br>
	<input type="submit" value="Upload File">
</form>

input标签里有一个 type 属性是 file,处理方式和之前非常相似:

import requests

files = {'uploadFile': open('python.JPG', 'rb')}
r = requests.post('http://pythonscraping.com/pages/processing2.php', files=files)
print(r.text)

此处uploadFile的值是一个由open 函数返回的 Python 文件对象。文件路径是相对这个Python 程序所在位置。
5.处理登录和cookie
大多数现代网站都用 cookie 跟踪用户是否已登录的状态信息。一旦网站验证了你的登录凭据,就会在你的浏览器上将其保存为一个 cookie,里面通常包含一个由服务器生成的令牌、登录有效时限和状态跟踪信息。网站会把这个 cookie 当作一种验证证据,在你浏览网站的每个页面时都出示给服务器。
pythonscraping.com网站有一个简单的登录表单(用户名可以是任意值,但密码必须是“password”),登录表单由welcome.php处理,访问profile.php需要是已登录状态。
用 Requests 库跟踪 cookie,代码如下:

import requests
params = {'username': 'Ryan', 'password': 'password'}
r = requests.post('http://pythonscraping/pages/cookies/welcome.php', params)
print('Cookie is set to:')
print(r.cookie.get_dict())
print('Going to profile page...')
r = requests.get('http://pythonscraping.com/pages/cookies/profile.php', cookies=r.cookies)
print(r.text)

上述代码向欢迎页面发送了一个登录参数,它的作用就像登录表单的处理器。然后我从请求结果中获取 cookie,打印登录状态的验证结果,然后再通过 cookies 参数把 cookie 发送到简介页面。
当面对的网站比较复杂,它经常暗自调整cookie,这是需要用到Requests库的session函数,代码如下:

import requests

session = requests.Session()

params = {'username': 'username', 'password': 'password'}
s = session.post('http://pythonscraping.com/pages/cookies/welcome.php', params)
print('Cookie is set to:')
print(s.cookies.get_dict())
print('Going to profile page...')
s = session.get('http://pythonscraping.com/pages/cookies/profile.php')
print(s.text)

在这里插入图片描述
会话(session)对象(通过调用 requests.Session() 获取)会持续跟踪会话信息,包括 cookie、header,甚至是 HTTP 协议的信息,比如 HTTPAdapter(为 HTTP和 HTTPS 的链接会话提供统一接口)。
写网络爬虫的时候,你可能想放手让 Requests 库替自己做所有的事情,但是持续关注 cookie 的状态,掌握它们可以控制的范围是非常重要的。这样可以避免痛苦地调试和分析网站的异常行为,节省很多时间。

HTTP基本接入认证
在发明 cookie 之前,处理网站登录的一种常用方法就是用 HTTP 基本接入认证(HTTP basic access authentication)。例如http://pythonscraping.com/pages/auth/login.php
Requests库有一个auth模块,专门用来处理HTTP认证:

import requests
#from requests.auth import AuthBase
from requests.auth import HTTPBasicAuth

auth = HTTPBasicAuth('ryan', 'password')
r = requests.post(url='http://pythonscraping.com/pages/auth/login.php', auth=auth)
print(r.text)

在这里插入图片描述
这看着像是一个普通的 POST 请求,但是有一个 HTTPBasicAuth 对象作为 auth 参数传
递到了请求中。
6.其他表单问题
网页表单是网络恶意机器人(malicious bots)酷爱的网站切入点。因此,现代网站经常
在 HTML 中采取很多安全措施,让表单不能被快速穿越。‘关于验证码(CPATCHA)的作用,13章介绍Python的图像处理和文本识别方法。若提交表单出现莫名其妙问题或者服务器一直以陌生的理由拒绝你,查看 14 章内容,其介绍蜜罐(honey pot)、隐含字段(hidden field),以及其他保护网页表单的安全措施。


分享:

低价透明

统一报价,无隐形消费

金牌服务

一对一专属顾问7*24小时金牌服务

信息保密

个人信息安全有保障

售后无忧

服务出问题客服经理全程跟进