关于python:爬虫系列穿越网页表单与登录窗口进行采集

6次阅读

共计 4927 个字符,预计需要花费 13 分钟才能阅读完成。

上一期咱们解说了数据标准化相干内容,首先对单词呈现的频率进行排序,之后对一些大小写进行转换,放大 2-gram 序列的反复内容。

当咱们真正迈出网络数据采集根底之门的时候,遇到的第一个问题可能是:“我怎么获取登录窗口背地的信息呢?”明天,网络正在朝着页面交互、社交媒体、用户产生内容的趋势一直地演进。表单和登录窗口是许多网站中不可或缺的组成部分。不过,这些内容还是比拟容易解决的。

到目前为止,以前的示例当中网络爬虫和大多数网站的服务器经行数据交互时,都是用 HTTP 协定的 GET 形式去申请信息。在这一篇文章中咱们重点介绍 POST 办法,即把信息推送给网络服务器进行存储和剖析。

页面表单基本上能够看成是一种用户提交 POST 申请的形式,但这种申请形式是服务器可能了解和应用的。就像网站的 URL 连贯何以帮忙用户发送 GET 申请一样,HTML 表单能够帮忙用户收回 POST 申请。当然咱们也能够用一点儿点麻本人创立这些申请,而后通过网络爬虫把他们提交给服务器。

Python Requests 库

尽管用 Python 规范库也能够管制网页表单,然而有时用一点儿语法糖能够让生存更苦涩。但你想做比 urllib 可能实现的根本 GET 申请更多事件时,能够看看 Python 规范库之外的第三方库。

Requests 库 就是这样一个善于解决那些简单的 HTTP 申请、cookie、header(响应头和申请头)等内容的 Python 第三方库。

上面是 Requests 的创建者 Kenneth Retiz 对 Python 规范库工具的评估:

Python 规范库 urllib2 为你提供了大多数 HTTP 性能,然而它的 API 十分差劲。这是因为它是通过许多年一步步建设起来的的——不同期间要面对的是不同的网络环境。于是为了实现最简略的工作,他须要消耗大量的工作(甚至要写整个办法)。
<br/>

<br/>

事件不应该这样简单,更不应该产生在 Python 里。

和任何 Python 第三方库一样,Requests 库也能够用其余第三方 Python 库管理器来装置,比方 pip,或者间接下载 Requests 库源代码来装置。

提交一个根本表单

大多数网页表单都由一些 HTML 字段、一个提交按钮、一个在表单解决实现之后跳转的“执行后果”(表单 action 的值)页面形成。尽管这些 HTML 字段通常由文字内容形成,也能够实现文件上传或其余非文字内容。

因为大多数支流网站都会在它们的 robots.txt 文件里注明禁止爬虫接入登录表单,相干介绍能够参考这篇文章:爬虫系列:爬虫所带来的道德风险与法律责任。

比方上面是一个表单的源代码:

<form action="index.php?c=session&a=login" method=post name="form1">
    <div class="input_title"> 用户名 </div>
    <div class="input_box" style="margin-bottom: 10px;">
        <input id='username' name="username" />
    </div>
    <div class="input_title"> 明码 </div>
    <div class="input_box">
        <input type="password" name="passwd" />
    </div>
    <div class="login_button">
        <input type="submit" value="登 录" />
    </div>
</form>

这里有几点须要留神一下:首先,两个输出字段的名称是 usernamepasswd,这一点十分重要。字段的名称决定了表单被确认后要被传送到服务器上的变量名称。如果你想模仿表单提交数据的行为,你就须要保障你的变量名称与字段名称是一一对应的。

还须要表单的实在行为其实产生在 index.php?c=session&a=login。表单的任何 POST 申请其实都是产生在这个页面上,并非表单自身所在的页面。切记:HTML 表单的目标,只是帮忙网站的访问者发送格局正当的申请,向服务器申请没有呈现的页面。除非你要对申请的设计款式进行钻研,否则就不要花太多工夫在表单所在的页面上。

应用 Requests 库提交表单只须要简略的几行代码就能够实现,包含导入库文件和打印内容的语句:

import requests

params = {'username': 'admin', 'passwd': '5e_KR&pXJ9=J(c7d9P-twt9:'}

r = requests.post("http://www.test.com/admin/index.php?c=session&a=login", data=params)
print(r.text)

表单被提交之后,程序会返回执行页面的源代码,这些内容如下:

<frameset name="right" rows="64,9,*" cols="*" frameborder="no" border="0" framespacing="0">
    <frame src="?c=index&a=top" name="top" noresize="noresize" scrolling="no">
    <frame src="?c=index&a=controltop" name="controltop" noresize="noresize" scrolling="no">
    <frameset cols="170,*" frameborder="no" border="0" framespacing="0" name="main1">
        <frame src="?c=index&a=left" name="left" scrolling="auto" noresize>
        <frame src="?c=index&a=main" name="main" scrolling="yes">
    </frameset>
</frameset>
<noframes>
    <body bgcolor='#FFFFFF' text='#000000'>
    您的浏览器不反对框架!</body>
</noframes>

因为咱们通过的是 Requests 提交的内容,并没有在浏览器中进行提交所以才会呈现下面的提醒,然而咱们曾经登录胜利了的。前面须要应用到浏览器采集内容的时候,咱们再详述这部分内容。

这面那段代码能够解决很多简略的表单。上面是一个邮件订阅的表单代码,如下:

<form data-formid="4ea5f424-2d32-44c7-b603-887d06d6bde0" novalidate>
    <input type="hidden" name="lifecyclestage" value="subscriber">
    <input type="hidden" name="content_language" value="English">
    <ul class="blog-subscribe-form__blog-list">
        <li style="display: none;">
            <input class="frequency" name="blog_default_blog_subscription" data-frequency="daily">
        </li>                           
        <li style="">
            <input type="checkbox" id="hs-marketing-blog-sticky" name="marketing_blog_subscribe_check_box_via_comments" data-frequency="daily" data-frequency-field="blog_default_blog_subscription" data-subscription-type-id="98684">
                <label for="hs-marketing-blog-sticky" class="blog-subscribe-form__checkbox">Marketing</label>
        </li>
    </ul>
    <ul class="hs-error-msgs inputs-list" role="alert">
        <li data-reactid=".hbspt-forms-0.1:$1.1:$email.3.$0">
            <label class="validation blog-list-validation"></label>
        </li>
    </ul>
    <div class="blog-subscribe-form__email-input-container">
        <div class="blog-subscribe-form__email-input">
            <label for="email-address">Email Address</label>
            <input type="email" placeholder=""id="email-address"name="email"value="" required>
        </div>    
    </div>
    <ul class="hs-error-msgs inputs-list" role="alert">
        <li data-reactid=".hbspt-forms-0.1:$1.1:$email.3.$0">
            <label class="validation email-validation"></label>
        </li>
    </ul>
    <input type="submit" value="Subscribe" class="blog-subscribe-form__button cta cta--primary-light cta--medium">
</form>

尽管第一次看到感觉有点恐怖,然而大多数状况下咱们只须要关注两件事:

  • 你想提交的数据字段名称,例如下面的 email
  • 表单的 action 属性,也就是表单提交后网站会显示的页面

单选按钮、复选按钮和其余输出

显然,并非所有的页面都只是一堆文本字段和一个提交按钮。HTML 规范外面提供了大量可用的表单字段:单选按钮、复选按钮、下拉选项等。在 HTML5 外面,还有其余的控件,像滚动条(范畴输出字段)、邮箱、日期等。自定义的 Javascript 字段堪称无所不能,能够实现取色器(colorpicker)、日历以及开发者能想到的任何性能。

无论表单的字段看起来如许简单,依然只有两件事须要关注:字段名称和值。字段名称能够查看源代码寻找 name 属性轻易获取。而字段值有的时候比较复杂,有可能是在表单提交之前通过 Javascript 生成的。取色器就是一个比拟奇怪的表单字段,他可能会用 #f5c26b 这样的值。

如果你不确定一个输出字段值的数据格式,有一些工具能够追踪浏览器正在通过网站收回或承受的 GET 和 POST 申请的内容。之前提到过,追踪 GET 申请成果最好也是最间接的伎俩就是查看网站的 URL 链接,如果 URL 链接像这样:

https://pdf-lib.org/Home/SearchResult?Keyword=zabbix

那么申请的表单可能会是这样:

<form action="/Home/SearchResult" method="get">
    <input type="text" value=""id="Keyword"name="Keyword">
    <input type="submit" value=""id="Search">
</form>

上面是一个比较复杂的表单提交示例:

如果你遇到了一个看起来比较复杂的 POST 表单,并且像查看浏览器向服务器传送了那些参数,最简略的办法就是用 Chrome 浏览器的审查元素(inspector)或开发者工具查看。

总结

因为篇幅起因,明天只解说了根本的表单、单选按钮、复选框和其余表单输出,以及如何通过 Requests 提交到服务器端。

在下一篇文章中咱们将解说提交文件、图像、解决登录、cookie、HTTP 根本接入认证和其余表单相干问题。

源代码曾经托管于 Github,地址:https://github.com/sycct/Scrape_1_1.git

如果有任何问题,欢送大家 issue。

正文完
 0