Python + 请求 + 分裂:发出多个并发'get'请求的最快/最佳方法是什么?



当前与其他学生一起参加网络刮擦课,我们应该向假人网站提出'获取'请求,解析它并访问另一个网站。

问题是,虚拟站点的内容仅持续几分钟并且消失,并且内容在一定间隔中恢复。在内容可用的时候,每个人都试图提出"获取"请求,因此我的只是悬挂,直到每个人都清除,内容最终消失了。因此,我最终无法成功提出"获取"请求:

import requests
from splinter import Browser    
browser = Browser('chrome')
# Hangs here
requests.get('http://dummysite.ca').text
# Even if get is successful hangs here as well
browser.visit(parsed_url)

所以我的问题是,在我得到答复之前,最快/最佳的"获取"请求是什么?

  1. 决定使用requestssplinter

    阅读有关请求:人类的http
    阅读有关Splinter

    的信息
  2. 相关

    阅读有关饲养的
    阅读有关阻止或非障碍的信息
    阅读有关超时的信息
    阅读有关错误和外观的信息

如果您能够获得不悬挂请求,则可以考虑重复的请求,例如:

while True:
    requests.get(...
    if request is succesfull:
        break
    time.sleep(1)

Gevent提供了运行异步网络请求的框架。

它可以修补Python的标准库,以便盒子 requestssplinter等现有库。

这是一个简短的示例,说明如何根据上述代码提出10个并发请求并获得其响应。

from gevent import monkey
monkey.patch_all()
import gevent.pool
import requests
pool = gevent.pool.Pool(size=10)
greenlets = [pool.spawn(requests.get, 'http://dummysite.ca')
             for _ in range(10)]
# Wait for all requests to complete
pool.join()
for greenlet in greenlets:
    # This will raise any exceptions raised by the request
    # Need to catch errors, or check if an exception was
    # thrown by checking `greenlet.exception`
    response = greenlet.get()
    text_response = response.text

也可以使用map和响应处理功能而不是get

有关更多信息,请参见Gevent文档。

在这种情况下,并发无济于事,因为服务器似乎是限制因素。一种解决方案是在超出间隔的时间间隔内发送请求,如果超过了间隔,请在几秒钟后再次尝试请求。然后逐渐增加两者之间的时间,直到获得所需的数据为止。例如,您的代码可能看起来像这样:

import time
import requests
def get_content(url, timeout):
    # raise Timeout exception if more than x sends have passed
    resp = requests.get(url, timeout=timeout)
    # raise generic exception if request is unsuccessful
    if resp.status_code != 200:
        raise LookupError('status is not 200')
    return resp.content

timeout = 5 # seconds
retry_interval = 0
max_retry_interval = 120
while True:
    try:
        response = get_content('https://example.com', timeout=timeout)
        retry_interval = 0        # reset retry interval after success
        break
    except (LookupError, requests.exceptions.Timeout):
        retry_interval += 10
        if retry_interval > max_retry_interval:
            retry_interval = max_retry_interval
        time.sleep(retry_interval)
# process response

如果需要并发,请考虑进行废弃项目。它使用扭曲的框架。在砂纸中,您可以用reactor.callLater(fn, *args, **kw)替换time.sleep或使用数百个中间件插件之一。

来自请求的文档:

如果远程服务器非常慢,则可以告诉请求等待 永远响应,通过无作为超时值,然后 取回一杯咖啡。

import requests
#Wait potentially forever
r = requests.get('http://dummysite.ca', timeout=None)
#Check the status code to see how the server is handling the request
print r.status_code

以2开头的状态代码表示请求已收到,理解和接受。200意味着该请求是成功并返回的信息。但是503表示服务器已重载或正在进行维护。

请求用于包括一个称为async的模块,该模块可以发送并发请求。现在是一个名为Grequests的独立模块您可以用它来无休止地提出并发请求,直到200响应:

import grequests
urls = [
'http://python-requests.org', #Just include one url if you want
'http://httpbin.org',
'http://python-guide.org',
'http://kennethreitz.com'
]
def keep_going():
    rs = (grequests.get(u) for u in urls) #Make a set of unsent Requests
    out = grequests.map(rs) #Send them all at the same time
    for i in out:
        if i.status_code == 200:
            print i.text
            del urls[out.index(i)] #If we have the content, delete the URL
            return
while urls:
    keep_going() 

相关内容

  • 没有找到相关文章

最新更新