【发布时间】:2013-11-03 20:29:03
【问题描述】:
我正在构建一个网络爬虫,它可以从数百万个域的列表中获取 1-3 页,我正在使用多线程 Python,我尝试过使用 httplib、httplib2、urllib、urllib2、urllib3、requests 和 curl(最快的)以及扭曲和scrapy,但它们都不允许我使用超过大约10 mbit的带宽(我有60 mbit的速度),通常最多可以使用100-300个线程,然后它导致请求失败。我也遇到了 php/curl 的这个问题。我有一个刮板,它可以从谷歌加上带有 urllib3 和线程模块(Python)的页面,并且最大化我的 100mbit 连接(我相信这可能是因为它正在重新使用同一个主机的开放套接字,而谷歌有一个快速网络响应)
这是我使用 pycurl 的脚本之一的示例,我正在从包含 url 的 csv 文件中读取 url。
import pycurl
from threading import Thread
from Queue import Queue
import cStringIO
def get(readq,writeq):
buf = cStringIO.StringIO()
while True:
url=readq.get()
c = pycurl.Curl()
c.setopt(pycurl.TIMEOUT, 15)
c.setopt(pycurl.FOLLOWLOCATION, 1)
c.setopt(pycurl.USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0')
c.setopt(c.WRITEFUNCTION, buf.write)
c.setopt(c.URL, url)
try:
c.perform()
writeq.put(url+' '+str(c.getinfo(pycurl.HTTP_CODE)))
except:
writeq.put('error '+url)
print('hi')
readq=Queue()
writeq=Queue()
import csv
reader=csv.reader(open('alldataunq2.csv'))
sites = []
ct=0
for l in reader:
if l[3] != '':
readq.put('http://'+l[3])
ct+=1
if ct > 100000:
break
t=[]
for i in range(100):
Thread(target=get,args=(readq,writeq)).start()
while True:
print(writeq.get())
瓶颈肯定是网络 IO,因为我的处理器/内存几乎没有被使用。有没有人成功编写过能够使用完整 100mbit 或更多连接的类似爬虫?
非常感谢任何关于如何提高抓取代码速度的意见
【问题讨论】:
-
很可能是您的 ISP 检测到您经常 ping 到许多不同的地址,并决定限制您的 Internet 连接...您在随后的正常 Internet 访问期间达到什么速度?
-
我已经对此进行了测试,在停止运行脚本后我可以立即使用 speedtest.net 达到 55-60 mbit 的速度但是我注意到在远程服务器上运行我的脚本时我的速度更快(也许网络连接更适合大量请求)我正在测试以下建议,到目前为止,我已经能够使用 scrapy-redis 在服务器(不使用我的家庭互联网连接)上实现 5MB/秒的速度点它似乎受到服务器的 cpu 的限制,所以这似乎是一个解决方案,我会在进行更多测试后更新这篇文章
标签: python web-scraping twisted scrapy urllib3