当你想编写更为复杂的网页爬虫的时候,你面临的第一个问题也许会是:“如何获取登陆页面后的信息?”,因为网络已经飞快地向互动、社交媒体、用户生成内容方向发展。表格和登陆就成为这些类型网站几乎不可或缺的主要组成。幸运的是,表单和登陆还是相对比较容易处理的。
截至当前,在我们之前的爬虫示例中,绝大部分与服务器的交互都是采用了HTTP GET方式去获取信息的。而在本章,我们所关注的是如何通过POST方式来向服务器提交信息用于存储和分析。
表单给用户提供了一种服务器可以理解并使用的,提交POST请求的简单方法。就像网址链接可以帮助用户格式化GET请求,HTML表单可以帮用户格式化POST请求。当然通过一小段代码,我们就可以轻松的通过爬虫来创建并提交表单。
尽管可以通过Python核心类库来操作网页表单,但有些时候更友好的代码可以让生活更美好。当你开始使用urllib类库的GET请求做更多事情的时候,放眼Python核心库之外也许更有帮助。
Requests类库在处理复杂HTTP请求、Cookies,请求头等方面更为高效,此处便是Requests类库的创建者Kenneth Reitz对Python核心工具的评价:
Python标准urlib2模块提供了你所需要的绝大多数HTTP功能,但是其API却很垃圾。它的创建是用于不同时间以及不同网页的,即使执行一个简单的任务也需要大量的工作(甚至重写方法等)。
事情并不应该如此,至少在Python中不应如此。
和其他Python类库一样,Requests类库可以通过Python第三方类库管理器如pip来安装,或者直接下载 源代码 进行安装。
绝大多数网页表单由部分HTML标签、提交按钮以及一个Action页(具体执行表单任务的网址)所组成。HTML标签一般含有文本标签不过有时候也包含文件上传或其他非文本内容标签。
大多数热门网站在robots.txt文件中屏蔽了针对登录表单的访问(详见附录C),因此为了更安全的玩耍,我在 pythonscraping.com 上创建了一系列不同类型的表单和登录页面。你可以运行你的爬虫来访问他们。其中最为简单的表单地址为: http://bit.ly/1AGKPRU
完整表单代码如下:
<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"> </form>
在此处需要注意的是:第一,两个input标签的名称为 firstname 和 lastname 。这个非常重要,这些标签的名称决定了要POST到服务器的表格变量的名称。如果你要模拟提交表格,并提交自定义内容,那么你需要确定你的变量名称与标签名称匹配。
第二需要注意的是表格实际提交到的执行页面是 processing.php (绝对路径为: http://bit.ly/1d7TPVk )。任何POST请求提交到表单都是 上述 (Action所指向的)地址,而不是包含表单的页面地址。记住:HTML表单的主要目的仅是帮助网站访问者格式化提交到处理页面的请求。除非你在研究如何格式化请求,那么你完全没有必要被包含表单的页面所困扰。
通过Requests类库提交一个表单可以使用4行代码完成,包括 import 以及 print 内容函数。
import requests params = {'firstname': 'Ryan', 'lastname': 'Mitchell'} r = requests.post("http://pythonscraping.com/pages/files/processing.php", data=params) print(r.text)
表单提交后,脚本会返回页面内容:
Hello there, Ryan Mitchell!
这个脚本可以被应用到许多互联网上的简单表单。例如,登录O‘Reilly媒体通讯的表单,如下所示:
<form action="http://post.oreilly.com/client/o/oreilly/forms/ quicksignup.cgi" id="example_form2" method="POST"> <input name="client_token" type="hidden" value="oreilly" /> <input name="subscribe" type="hidden" value="optin" /> <input name="success_url" type="hidden" value="http://oreilly.com/store/ newsletter-thankyou.html" /> <input name="error_url" type="hidden" value="http://oreilly.com/store/ newsletter-signup-error.html" /> <input name="topic_or_dod" type="hidden" value="1" /> <input name="source" type="hidden" value="orm-home-t1-dotd" /> <fieldset> <input class="email_address long" maxlength="200" name= "email_addr" size="25" type="text" value= "Enter your email here" /> <button alt="Join" class="skinny" name="submit" onclick= "return addClickTracking('orm','ebook','rightrail','dod' );" value="submit">Join</button> </fieldset> </form>
尽管第一次开起来上述代码有点吓人,不过要记住在绝大多数案例中(我们稍后会讲到其他例外),你只需要关注两个事情:
提交数据字段的名称(在这个例子中,字段名称是email_address)
表单的action属性,也就是表单真正提交到的那个页面(在这个例子中,就是 http://post.oreilly.com/client/o/oreilly/forms/quicksignup.cgi )
添加需要的信息并运行:
import requests params = {'email_addr': 'ryan.e.mitchell@gmail.com'} r = requests.post("http://post.oreilly.com/client/o/oreilly/forms/ quicksignup.cgi", data=params) print(r.text)
在这个例子中,当你可以真正进入O'Reilly的邮件列表前,网站返回了另一个需要填写的表单。不过同样的原理可以应用到这个新表单上。不过,当你在家自己尝试的时候,我需要你保证正当利用这个技术,而不是通过无效注册给发布者制造垃圾邮件。
不断更新中……
原文:《 Web Scraping with Python 》
翻译:Yishi