好的,我需要使用Python下载一些网页,并快速调查我的选项.
包含在Python中:
urllib - 在我看来,我应该使用urllib2代替.urllib没有cookie支持,只有HTTP/FTP /本地文件(没有SSL)
urllib2 - 完整的HTTP/FTP客户端,支持最需要的东西,如cookie,不支持所有HTTP动词(只有GET和POST,没有TRACE等)
功能齐全:
机械化 - 可以使用/保存Firefox/IE cookie,采取跟随第二个链接的行动,积极维护(2011年3月发布0.2.5)
PycURL - 支持curl所做的一切(FTP,FTPS,HTTP,HTTPS,GOPHER,TELNET,DICT,FILE和LDAP),坏消息:自2008年9月9日起未更新(7.19.0)
新的可能性:
urllib3 - 支持连接重用/池和文件发布
不推荐使用(也就是使用urllib/urllib2):
httplib - 仅限HTTP/HTTPS(无FTP)
httplib2 - 仅限HTTP/HTTPS(无FTP)
让我印象深刻的第一件事是urllib/urllib2/PycURL/mechanize都是非常成熟的解决方案,效果很好.机械化和PycURL附带了许多Linux发行版(例如Fedora 13)和BSD,所以安装通常不是问题(所以这很好).
urllib2看起来不错,但我想知道为什么PycURL和机械化看起来都非常受欢迎,是否有一些我缺少的东西(即如果我使用urllib2,我会在某个角落将自己画到一个角落?).我真的很喜欢这些事情的优点/缺点的反馈,所以我可以为自己做出最好的选择.
编辑:在urllib2中添加了关于动词支持的注释
好吧,这是一个比它听起来更棘手的问题,所以我转向堆栈溢出,因为我想不出一个好的答案.这就是我想要的:我需要Python以随机顺序生成一个简单的0到1,000,000,000的数字列表,用于序列号(使用随机数,这样你就无法分辨已经分配了多少或做了时间攻击很容易,即猜测下一个会出现的问题).这些数字与链接到它们的信息一起存储在数据库表(索引)中.生成它们的程序不会永远运行,因此它不能依赖于内部状态.
没什么大不了的?只需生成一个数字列表,将它们推入一个数组并使用Python"random.shuffle(big_number_array)",我们就完成了.问题是我想避免必须存储一个数字列表(从而读取文件,弹出一个顶部,保存文件并关闭它).我宁愿在飞行中生成它们.问题是我能想到的解决方案有问题:
1)生成一个随机数,然后检查它是否已被使用.如果已经使用它生成一个新的数字,检查,根据需要重复,直到找到一个未使用的数字.这里的问题是,在获得未使用的数字之前,我可能会感到不幸并生成大量使用过的数字.可能的解决方法:使用一个非常大的数字池来减少这种情况的可能性(但最后我得到了愚蠢的长数字).
2)生成一个随机数,然后检查它是否已被使用.如果已经使用了从数字中添加或减去一个并再次检查,请继续重复,直到我点击未使用的数字.问题是这不再是随机数,因为我已经引入了偏见(最终我会得到一堆数字,你可以预测下一个数字有更大的成功机会).
3)生成一个随机数,然后检查它是否已被使用.如果它已被使用添加或减去另一个随机生成的随机数并再次检查,问题是我们回到简单地生成随机数并检查解决方案1.
4)将其取出并生成随机列表并保存,让守护程序将它们放入队列中,以便有可用的数字(并避免不断打开和关闭文件,而是将其批处理).
5)生成更大的随机数并散列它们(即使用MD5)来获得更小的数值,我们应该很少得到冲突,但最终我的数字大于所需的数字.
6)在随机数(即unix时间戳)之前添加或附加基于时间的信息以减少碰撞的可能性,同样我得到的数字比我需要的数字更多.
任何人都有任何聪明的想法,可以减少"碰撞"的机会(即产生一个已经采取的随机数),但也可以让我保持这个数字"小"(即少于十亿(或十亿)你的欧洲人=)).
答案以及为什么我接受它:
因此,我将简单地选择1,并希望它不是一个问题,但是如果是的话,我会选择生成所有数字并存储它们的确定性解决方案,以便有一个获得新的随机数的保证,我可以使用"小"数字(即9位数而不是MD5 /等).
我没有本地代码副本/ etc,我只想下载一个特定的git提交,以便我可以查看它.我有git存储库的url:
混帐://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
和提交哈希:
ee9c5cfad29c8a13199962614b9b16f1c4137ac9
Run Code Online (Sandbox Code Playgroud)
我如何使用git下载这个提交(我不想要整个repo,只需要一个提交补丁)?我已经阅读了git-pull和git-cherry-pick的手册页,并且在没有运气的情况下摆弄了这些命令.
克隆存储库确实不是一种选择,因为某些内核存储库非常大且下载速度慢(小时).
所以我正在研究urllib3,因为它有连接池并且是线程安全的(因此性能更好,特别是对于爬行),但文档是......最小的说法.urllib2有build_opener,所以类似于:
#!/usr/bin/python
import cookielib, urllib2
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
r = opener.open("http://example.com/")
Run Code Online (Sandbox Code Playgroud)
但是urllib3没有build_opener方法,所以到目前为止我唯一想到的方法是手动将它放在标题中:
#!/usr/bin/python
import urllib3
http_pool = urllib3.connection_from_url("http://example.com")
myheaders = {'Cookie':'some cookie data'}
r = http_pool.get_url("http://example.org/", headers=myheaders)
Run Code Online (Sandbox Code Playgroud)
但我希望有更好的方法,你们中的一个人可以告诉我它是什么.也可以有人用"urllib3"标记这个.
所以lxml有一个非常简单的功能:make_links_absolute:
doc = lxml.html.fromstring(some_html_page)
doc.make_links_absolute(url_for_some_html_page)
Run Code Online (Sandbox Code Playgroud)
现在,doc中的所有链接都是绝对的.在BeautifulSoup中是否有一个简单的等价物,或者我只需要通过urlparse传递它并将其标准化:
soup = BeautifulSoup(some_html_page)
for tag in soup.findAll('a', href=True):
url_data = urlparse(tag['href'])
if url_data[0] == "":
full_url = url_for_some_html_page + test_url
Run Code Online (Sandbox Code Playgroud)