首页 > 解决方案 > Python在beautifulsoup中实现多线程或workerpool或multiprocession,用于一次抓取多个url

问题描述

import requests
from bs4 import BeautifulSoup

urls = ['http://www.freejobalert.com/upsc-advt-no-18/33742/',
        'http://www.freejobalert.com/upsc-recruitment/16960/#Engg-Services2019',
        'http://www.freejobalert.com/ssc-recruitment/17522/#selection-posts']

for u in urls:
    page = requests.get(u)
    c = page.content
    soup = BeautifulSoup(c, "html5lib")
    row = soup.find_all("table", {"style":"width: 500px;"})[0].find_all('tr')
    dict = {}

    for i in row:
        for title in i.find_all('span', attrs={'style': 'color: #008000;'}):
            dict['Title'] = title.text

        for link in i.find_all('a', attrs={'title':'UPSC'}, href=True):
            dict['Link'] = link['href']
            print(dict)

在这里,我一次从多个 URL 中抓取一些特定数据。所以它非常慢,并且需要更多时间意味着一个 URL 的 3 倍。

有什么方法可以在 python 中使用“workerpool”或“threading”或“multiprocessing”使其快速运行。

请帮我整合它

标签: python

解决方案


你可以把你的

def your_function(u):
    page = requests.get(u)
    c = page.content
    soup = BeautifulSoup(c,"html5lib")
    row = soup.find_all("table",{"style":"width: 500px;"})[0].find_all('tr')
    dict = {}
    for i in row:
        for title in i.find_all('span', attrs={
    'style':'color: #008000;'}):
            dict['Title'] = title.text
        for link in i.find_all('a',attrs={'title':'UPSC'}, href=True):
            dict['Link'] = link['href']
     return dict

在函数中并使用 pool.map (多处理)

from multiprocessing.dummy import Pool as ThreadPool
pool = ThreadPool(4) # put your number of CPU
results = pool.map(your_function,urls)

基本上,这就像将函数应用于可迭代对象的每个元素(您将使用 map 执行的操作),但以并行方式。

它比传统的基于队列的并行方法更容易。 一篇关于它的好文章


推荐阅读