6

我想要做的是从请愿书上的一个或多个请愿书中刮取请愿数据——姓名、城市、州、日期、签名号。

我假设在这一点上 python 是要走的路——可能是 scrapy 库——以及一些处理网站 ajax 方面的函数。这个爬虫的原因是这个请愿数据不向公众提供。

我是一名自由科技记者,我希望能够将每个请愿书的数据转储到 CSV 文件中,以便分析每个州签署该州请愿书的人数,并使用来自多个请愿书的数据,找出人数谁签署了多个请愿书等,然后对请愿过程的政治可行性和数据本身做出一些结论。

请愿书.whitehouse.gov 上的请愿功能作为 Drupal 模块运行,白宫开发人员在 github https://github.com/WhiteHouse/petition/issues/44上回复了我的问题请求,他们正在开发一个 API允许从模块访问请愿数据。但是该 API 没有发布日期;这并不能解决目前在请愿书.whitehouse.gov 上的请愿书数据的问题。

我已经给白宫和白宫开发商发了电子邮件,说我是一名自由记者,并要求通过某种方式访问​​数据。白宫数字战略办公室告诉我,“很遗憾,我们目前无法提供数据导出,但我们正在努力通过 API 开放数据。” 白宫有一项“开放数据”倡议,但显然没有涵盖请愿数据。

隐私和服务条款:签署请愿书时几乎没有隐私。并且没有明确的 TOS 可以解决这些数据的网络抓取问题。

已经做了什么: UNC 的一些教师已经编写(我假设是)一个 python 脚本来抓取数据,但他们不想将脚本发布给我,说他们仍在研究它。http://www.unc.edu/~ncaren/secessionists/他们确实给我发了一份我特别感兴趣的请愿书的 CSV 数据转储。

我所做的:我为此建立了一个 github 项目,因为我希望任何请愿数据抓取工具对每个人都有用——请愿者自己、记者等——他们希望能够获得这些数据。https://github.com/markratledge/whitehousescraper

我没有使用 python 的经验,也没有使用 shell 脚本的经验,而我目前正在尝试做的事情显然超出了我的经验。

我运行了一个 GUI 脚本,每五秒左右向网络浏览器发送一个“空格键”,然后通过将浏览器文本剪切并粘贴到文本编辑器中来刮掉大约 10,000 个签名。从那里,我可以用 grep 和 awk 将文本处理成 CSV 格式。当然,这不太好。Chrome 因页面大小而陷入困境,需要数小时才能获得这么多签名。

到目前为止我发现了什么:从我可以从其他 SO 问题和答案中收集到的内容,看起来 Python 和 scrapy http://scrapy.org是避免浏览器问题的方法。但是该页面使用 ajax 函数来加载下一组签名。看起来这是一个“静态”ajax 请求,因为 URL 没有改变。

在 Firebug 中,JSON 请求标头似乎有一个随机字符串附加到它们前面,并带有一个页码。这是否说明了需要做什么?脚本是否需要模拟并将这些发送到网络服务器?

请求网址:https://petitions.whitehouse.gov/signatures/more/50ab2aa8eab72abc4a000020/2/50b32771ee140f072e000001 请求网址:https://petitions.whitehouse.gov/signatures/more/50ab2aa8eab72abc4a000020/3/50b1040f6ce60061c837e0000 请求网址: /petitions.whitehouse.gov/signatures/more/50ab2aa8eab72abc4a000020/4/50afb3d7c988d47504000004

这是在页面上加载签名的 JS 函数:

(function ($) {
Drupal.behaviors.morePetitions = {
  attach: function(context) {
    $('.petition-list .show-more-petitions-bar').unbind();
    $(".petition-list .show-more-petitions-bar").bind('click',
      function () {
        $('.show-more-petitions-bar').addClass('display-none');
        $('.loading-more-petitions-bar').removeClass('display-none');

        var petition_sort = retrieveSort();
        var petition_cols = retrieveCols();
        var petition_issues = retrieveIssues();
        var petition_search = retrieveSearch();
        var petition_page = parseInt($('#page-num').html());

        var url = "/petitions/more/"+petition_sort+"/"+(petition_page + 1)+"/"+petition_cols+"/"+petition_issues+"/"+petition_search+"/";
        var params = {};
        $.getJSON(url, params, function(data) {
          $('#petition-bars').remove();
          $('.loading-more-petitions-bar').addClass('display-none');
          $('.show-more-petitions-bar').removeClass('display-none');
          $(".petition-list .petitions").append(data.markup).show();

          if (typeof wh_petition_adjustHeight == 'function') {
            wh_petition_adjustHeight();
          }

          Drupal.attachBehaviors('.petition-list .show-more-petitions-bar');
          if (typeof wh_petition_page_update_links == 'function') {
            wh_petition_page_update_links();
          }
        });

        return false;
      }
    );
  }
}

并且在滚动到浏览器窗口底部时显示此 div 时触发:

<a href="/petition/.../l76dWhwN?page=2&amp;last=50b3d98e7043012b24000011" class="load-next no-follow active" rel="509ec31cadfd958d58000005">Load Next 20 Signatures</a>
<div id="last-signature-id" class="display-none">50b3d98e7043012b24000011</div>

那么,最好的方法是什么?我该去哪里使用scrapy?还是有另一个更适合这个的python库?

随意发表评论,用代码片段为我指明方向,其他 SO 问题/答案,为 github 做出贡献。在这一点上,我正在尝试做的显然超出了我的经验。

4

2 回答 2

1

“随机链接”看起来像以下形式:

https://petitions.whitehouse.gov/signatures/more/petitionid/pagenum/lastpetition 其中请愿ID对于单个请愿是静态的,pagenum每次递增,并且每次从请求中返回lastpetition 。

我通常的方法是使用 requests 库来模拟 cookie 的会话,然后计算出浏览器发出的请求。

import requests
s=requests.session()
url='http://httpbin.org/get'
params = {'cat':'Persian',
          'age':3,
          'name':'Furball'}             
s.get(url, params=params)

我会特别注意以下链接:

<a href="/petition/shut-down-tar-sands-project-utah-it-begins-and-reject-keystone-xl-pipeline/H1MQJGMW?page=2&amp;last=50b5a1f9ee140f227a00000b" class="load-next no-follow active" rel="50ae9207eab72aed25000003">Load Next 20 Signatures</a>

于 2012-11-28T10:27:41.627 回答
0

很难用 Python 完全模拟 Jquery/Javascript。 你可以看看 spidermonkey 或像 Selenium 这样的网络测试自动化工具,它可以完全自动化任何浏览器操作。关于 SO 的上一个问题: Python 如何与 javascript 一起工作

于 2012-11-27T17:38:22.797 回答