【问题标题】:python3 urllib.request will block forever in geventpython3 urllib.request 将在 gevent 中永远阻塞
【发布时间】:2014-11-09 14:40:49
【问题描述】:

我想编写一个蜘蛛程序来使用python3中的gevent下载网页。这是我的代码:

import gevent
import gevent.pool
import gevent.monkey
import urllib.request

gevent.monkey.patch_all()

def download(url):
    return urllib.request.urlopen(url).read(10)

urls = ['http://www.google.com'] * 100
jobs = [gevent.spawn(download, url) for url in urls]
gevent.joinall(jobs)

但是当我运行它时,出现错误:

Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/gevent/greenlet.py", line 340, in run
result = self._run(*self.args, **self.kwargs)
File "e.py", line 8, in download
return urllib.request.urlopen(url).read(10)
File "/usr/lib/python3.4/urllib/request.py", line 153, in urlopen
return opener.open(url, data, timeout)

......
return greenlet.switch(self)
gevent.hub.LoopExit: This operation would block forever
<Greenlet at 0x7f4b33d2fdf0: download('http://www.google.com')> failed with LoopExit
......

似乎 urllib.request 阻塞了,所以程序无法运行。如何解决?

【问题讨论】:

标签: python web-crawler block gevent


【解决方案1】:

这可能是由于在公司网络中设置了代理。个人推荐使用 Selenium 结合美汤,使用浏览器打开 url 链接,可以下载 html 内容,也可以直接控制浏览器。希望对你有帮助

from selenium import webdriver
from bs4 import BeautifulSoup
browser = webdriver.Ie()
url = "http://www.google.com"
browser.get(url)
html_source = browser.page_source
soup = BeautifulSoup(html_source, "lxml")
print(soup)
browser.close()

【讨论】:

    【解决方案2】:

    Python, gevent, urllib2.urlopen.read(), download accelerator中的问题相同。

    重申上述帖子:

    要读取的参数是字节数,而不是偏移量。

    还有:

    您正在尝试读取来自不同 greenlets 的单个请求的响应。

    如果您想使用多个并发连接下载同一个文件,那么如果服务器支持,您可以使用 Range http 标头(对于带有 Range 标头的请求,您将获得 206 状态而不是 200)。请参阅 HTTPRangeHandler。

    【讨论】:

    • 我还必须补充一点,众所周知,'requests' 包与'gevents' 冲突,因为它以 1 字节的块大小读取响应正文,正如我在某处读到的那样。不要使用它。
    猜你喜欢
    • 2015-12-23
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多