剖析Aaron Swartz用来从Jstor档案库下载数千篇文章的脚本

Pat*_*ris 5 python web-scraping python-2.7

亚伦·斯沃兹(Aaron Swartz)在早期塑造互联网的过程中发挥了重要作用。对于熟悉Aaron的人来说,您可能知道他因从jstor档案馆,一个学术期刊和书籍的数字图书馆中下载了大量文章而面临长达35年的监禁后自杀。他用来下载文章的脚本已发布,如下图所示。(这是亚伦的纪录片的链接,供那些有兴趣的人使用。)

keepgrabbing.py

这是代码:

import subprocess, urllib, random
class NoBlocks(Exception): pass
def getblocks():
    r = urllib.urlopen("http://{?REDACTED?}/grab").read()
    if '<html' in r.lower(): raise NoBlocks
    return r.split()


import sys
if len(sys.argv) > 1:
    prefix = ['--socks5', sys.argv[1]]
else:
    prefix = []#'-interface','eth0:1']
line = lambda x: ['curl'] + prefix + ['-H', "Cookie: TENACIOUS=" + str(random.random())[3:], '-o', 'pdfs/' + str(x) + '.pdf', "http://www.jstor.org/stable/pdfplus/" + str(x) + ".pdf?acceptTC=true"]


while 1:
    blocks = getblocks()
    for block in blocks:
        print block
        subprocess.Popen(line(block)).wait()
Run Code Online (Sandbox Code Playgroud)

我想这是一种敬意。我一直深受亚伦的故事和逝世的影响。他是互联网的杰出开创者,创立了创意共享空间,Web提要格式RSS和Reddit,所有这些都在他26岁那年过世之前。

我想尽我所能了解这次导致一名男子死亡的事件,他为互联网及其不断发展的用户社区做出了许多伟大的贡献。

语境

Jstor是一个大型学术出版物图书馆。当Aaron在2010年从他们的档案库中下载文章时,麻省理工学院的学生可以免费使用JSTOR,但公众则不能免费使用。尽管我们不确切知道亚伦想对这些信息做些什么,但是他想将其传播给那些无法访问的人是一个安全的赌注。

我的问题

我看到他创建了一个函数Getblocks(),该函数使用该urllib模块访问Jstor的数字档案,将网页的HTML读取为变量并将页面内容拆分。

从他导入sys模块到if / else语句的结尾,这是我不理解的代码的命令行部分。

他创建了一个命令行参数,可以定义..什么?他在这里做什么?

如果命令行参数的长度小于1,并且调用else条件,那么他的lambda函数在这里完成了什么工作?

if len(sys.argv) > 1:
    prefix = ['--socks5', sys.argv[1]]
else:
    prefix = []#'-interface','eth0:1']
line = lambda x: ['curl'] + prefix + ['-H', "Cookie: TENACIOUS=" + str(random.random())[3:], '-o', 'pdfs/' + str(x) + '.pdf', "http://www.jstor.org/stable/pdfplus/" + str(x) + ".pdf?acceptTC=true"]
Run Code Online (Sandbox Code Playgroud)

如果您对Aaron大型文件筛选机制有任何见解,将不胜感激。

放轻松,亚伦。

附加条款

有关此案的法律文件可在此处找到。在这些文件中,有一个链接指向亚伦下载所有文件后Jstor员工之间的几次对话。在一次电子邮件交流中,一位Jstor员工描述了Aaron如何规避了“要下载的IP会话”规则。

“通过清除cookie并开始新的会话,他们有效地避开了Literatum中的滥用工具。...每个IP规则的会话数未触发,因为它是基于服务器的,并且用户的负载平衡不止几个8500个会话只需要两个服务器就可以规避规则。我们可以降低会话数量,但要求数据找到有效的级别以捕获事件,而不会干扰其他地方的正常用户。有了我们的MDC和服务器数量,不能同时实现这两个目标。”

Blc*_*ght 3

您对代码图像的转录缺少最后一行,这非常关键。在循环内部,它subprocess.Popen调用 lambda 函数的输出line

subprocess.Popen(line(block)).wait()
Run Code Online (Sandbox Code Playgroud)

getblocks函数从经过编辑的网站(可能不是 jstor)读取数据以获取要下载的 pdf 文件列表。这允许远程控制脚本。

lambdaline函数生成一个命令行参数列表,用于Popen调用curl命令行实用程序,该程序执行实际的下载。在“附加注释”部分的引用中提到的 cookie 在 lambda 中生成(它生成一个随机数,将其转换为字符串,然后对除前三个字符之外的所有字符进行切片以获取 cookie 值)。