我正在构建一个网络爬虫,它可以从数百万个域的列表中获取 1-3 页,我正在使用多线程的 Python,我尝试过使用 httplib、httplib2、urllib、urllib2、urllib3、请求和 curl 的多线程(最快的一堆)以及扭曲和scrapy,但它们都不允许我使用超过约10 mbits的带宽(我有60 mbit的速度),通常在大约100-300个线程时达到最大值,之后它会导致失败的请求. 我也遇到了 php/curl 的这个问题。我有一个刮板,它从谷歌加上带有 urllib3 和 Threads 模块(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 或更多连接的类似刮板?
非常感谢有关如何提高抓取代码速度的任何输入