我想要做的是从请愿书上的一个或多个请愿书中刮取请愿数据——姓名、城市、州、日期、签名号。
我假设在这一点上 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&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 做出贡献。在这一点上,我正在尝试做的显然超出了我的经验。