【发布时间】:2020-06-16 23:52:29
【问题描述】:
我正在尝试从 url 列表中抓取一些信息,并希望异步执行以节省时间。当我同步这样做时,我能够获得我想要的信息,并且该代码的相关部分基本上是这样的:
links = [...] #list of links
for link in links:
source_race = requests.get(link).text
soup_race = BeautifulSoup(source_race,'lxml')
contestant_names = []
for contestants in soup_race.find_all('div',attrs={'data-automation-id':'racecard-outcome-name'}):
contestant_names.append(contestants.text.replace('\xa0',' '))
这会返回一个参赛者姓名列表,这正是我想要的。
现在,当我尝试异步执行此操作时,我正在使用打印功能在初步阶段对其进行测试,如下所示:
reqs = (grequests.get(link) for link in links)
resp = grequests.map(reqs)
for r in resp:
soup = BeautifulSoup(r.text, 'lxml')
results = soup.find_all('div',attrs={'data-automation-id':'racecard-outcome-name'})
print(results)
但我没有得到文本项,我只是得到了该页面上所有这些细节的完整列表。输出看起来像(我无法捕获整个输出,但它是一个很长的列表,包含我想要的所有信息,但我无法提取我想要的特定文本项,我已经圈了出来,它们只是名称和括号中的数字):
当我尝试输入 print(results.text) 时,出现以下错误:
当我将上面的代码更改为find 而不是find_all,并使用print(results.text) 时,我得到的结果完全符合我的预期(并且希望),即:
我只需要一种方法来打印所有跑步者的名字。
我对异步网络抓取(以及一般的网络抓取)是全新的,所以如果有任何不清楚的地方,我很抱歉。
【问题讨论】:
-
您需要为此使用 asyncio。
-
谢谢。我对此进行了一些研究,并使其发挥了作用。
-
不幸的是,由于请求的快速触发性质,我被暂时禁止访问该网站。看来我需要轮换一堆 IP 地址来解决这个问题。像:
conn = aiohttp.TCPConnector(local_addr=('127.0.0.1', 0), loop=loop)async with aiohttp.ClientSession(connector=conn) as session:(显然带有随机选择的 IP 地址列表)是正确的路径吗? -
@TNoms 你试过了吗,结果如何?
标签: python asynchronous web-scraping grequests