4

我尝试组织最多 10 个并发下载的池。该函数应下载基本 url,然后解析此页面上的所有 url 并下载每个 url,但并发下载的总数量不应超过 10。

from lxml import etree 
import gevent
from gevent import monkey, pool
import requests

monkey.patch_all()
urls = [
    'http://www.google.com', 
    'http://www.yandex.ru', 
    'http://www.python.org', 
    'http://stackoverflow.com',
    # ... another 100 urls
    ]

LINKS_ON_PAGE=[]
POOL = pool.Pool(10)

def parse_urls(page):
    html = etree.HTML(page)
    if html:
        links = [link for link in html.xpath("//a/@href") if 'http' in link]
    # Download each url that appears in the main URL
    for link in links:
        data = requests.get(link)
        LINKS_ON_PAGE.append('%s: %s bytes: %r' % (link, len(data.content), data.status_code))

def get_base_urls(url):
    # Download the main URL
    data = requests.get(url)
    parse_urls(data.content)

如何组织它以并发方式,但保持所有 Web 请求的一般全局池限制?

4

3 回答 3

8

我认为以下内容应该可以满足您的需求。我在我的示例中使用 BeautifulSoup 而不是您拥有的链接条带化的东西。

from bs4 import BeautifulSoup
import requests
import gevent
from gevent import monkey, pool
monkey.patch_all()

jobs = []
links = []
p = pool.Pool(10)

urls = [
    'http://www.google.com', 
    # ... another 100 urls
]
    
def get_links(url):
    r = requests.get(url)
    if r.status_code == 200:
        soup = BeautifulSoup(r.text)
        links.extend(soup.find_all('a'))

for url in urls:
    jobs.append(p.spawn(get_links, url))
gevent.joinall(jobs)
 
于 2013-12-07T00:44:50.270 回答
4

gevent.pool 将限制并发的greenlets,而不是连接。

您应该使用会话HTTPAdapter

连接限制 = 10
适配器 = requests.adapters.HTTPAdapter(pool_connections=connection_limit,
                                        pool_maxsize=connection_limit)
会话 = 请求。会话()
session.mount('http://', 适配器)
session.get('一些网址')
# 或者用 gevent 做你的工作
从 gevent.pool 导入池
# 如果处理数据的时间应该大于连接限制
# 比唐宁长,
# 进行更改运行处理。
池大小 = 15
池 = 池(池大小)
对于网址中的网址:
    pool.spawn(session.get, url)
于 2013-05-08T05:06:54.740 回答
0

您应该使用gevent.queue以正确的方式执行此操作。

(eventlet示例)也将有助于您理解基本思想。

Gevent 解决方案类似于 eventlet。

请记住,将有某个地方存储访问过的 URL,以免发生循环,因此您不会出现内存不足的错误,您需要引入一些限制。

于 2013-03-10T13:33:27.253 回答