在池的星图python中使用zip、itertools.count和itertools.repeat

2024-10-04 07:36:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试制作一个单线程单进程web scraper,我编写了多进程代码,因此效率更高

假设我有一个函数调用scan_page,它接受两个参数:第一个是会话实例,第二个是一个整数,表示必须刮取的页面数。该函数返回一个带有所需信息的pandas.DataFrame。 比如说:

from itertools import count, repeat
import pandas as pd
from multiprocessing import Pool


def scan_page(session, n, raise_exception_if_empty=False):
    print('scanning page #', n)
    r = (session.get(gen_url_paged(n)))
    assert r.status_code == 200
    bs = BS(r.content, 'lxml')
    trs = bs.find_all('tr')
    rows = []
    if raise_exception_if_empty:
        if len(trs) < 2:
            raise ValueError('Empty Page Found')
    for tr in trs:
        tds = tr.findChildren('td')
        if len(tds) > 0:
            rows.append(prepare_data(tds))
    return pd.DataFrame(rows)

到目前为止,我已经能够使用池对其进行多处理:

with Pool() as p:
    dfs = p.starmap(scan_page, zip(repeat(s), range(1,300)))
    df = pd.concat(dfs)

问题是我希望它是动态的,我不想扫描300页,如果在第12页它得到一个空页面(并返回一个空df)。但是如果我设置了raise_exception_if_empty=True,那么会引发一个异常,并且我会丢失到目前为止捕获的内容。我该怎么做

解决方案1: 这不是一个完全可行的解决方案,只是一个想法: 使用zip我可以传递到starmapzip(repeat(s), count(1)),但是我仍然需要找到一种方法在它到达一个空页面时停止它


Tags: importscanif进程pageexception页面tr