python3 urllib.request将永远阻止在gevent中

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python3 urllib.request将永远阻止在gevent中相关的知识,希望对你有一定的参考价值。

我想编写一个蜘蛛程序,在python 3中使用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阻塞,所以程序无法工作。怎么解决?

答案

这可能是由于代理在公司网络内时的设置。个人推荐使用Selenium结合美丽的汤,使用浏览器打开网址链接,你可以下载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()
另一答案

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

从上述帖子重申:

read的参数是多个字节,而不是偏移量。

也:

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

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

以上是关于python3 urllib.request将永远阻止在gevent中的主要内容,如果未能解决你的问题,请参考以下文章

爬虫小探-Python3 urllib.request获取页面数据

在python3中使用urllib.request编写简单的网络爬虫

Python3 urllib.request库的基本使用

python3 urllib学习

python3.4中urllib 有没有urlencode函数

python3 import urllib.request错误求解