我试图通过网络API获取整个Old Bailey Online档案的子集。
我的问题是我的实现不仅很慢,而且服务器很快就会停止服务我的请求(大约10分钟)。
目前我正在使用urllib3的开发版本:
import urllib3
retry = urllib3.util.Retry(total=1000, read=200, connect=200, backoff_factor=0.5)
timeout = urllib3.util.Timeout(connect=2.0, read=4.0)
http=urllib3.PoolManager(retry=retry, timeout=timeout, maxsize=10)
然后我用这个http池运行我的所有请求。我选择的数字相当荒谬,但最好的还是8(
每年,我需要提出70个并发请求,超过243年,并针对不同的情况。 我尝试使用@shazow的workerpool(根据https://stackoverflow.com/a/24046895/398969修改为与python3.4一起工作),同时在一年内,多线程年份,这也没有太好用。主要是由于服务器超时和我的无知。
DNS查找引入了明显的延迟吗?我不能使用Ip,因为域是一个apache虚拟主机(或者我可以吗?)
洙。真正的问题:如何“很好地”及时地从同一台服务器上下载数十万次?我仍然期待它需要一天左右的时间8)
答案 0 :(得分:1)
听起来服务器可能会因过于频繁地提出太多请求而限制/禁止您的IP。
首先,我建议检查域上的robots.txt,看看是否有关于自动请求频率的指导。如果没有,您可以要求网站所有者就如何最好地抓取网站提出建议。否则,您可能需要通过实验确定速率限制。
要限制您的请求,您可以使用apiclient。RateLimiter *(source)之类的内容。它看起来像这样:
from apiclient import RateLimiter
from urllib3 import PoolManager
lock = RateLimiter(max_messages=30, every_seconds=60)
http = PoolManager(...)
...
for url in crawl_list:
lock.acquire()
r = http.request(...)
您可以做的另一件事是抓取网站的缓存版本(如果可以通过Google或archive.org访问)。
[*] 免责声明:很久以前我也写过了apiclient。它没有超级记录。我怀疑如果你发现它缺乏,你可以使用其他类似的模块,但源码应该相当容易理解和扩展。