【问题标题】:Script throws some error at some point within the execution脚本在执行过程中的某个时间点抛出一些错误
【发布时间】:2019-06-15 07:31:51
【问题描述】:

我在 python 中创建了一个脚本,使用 pyppeteer 从网页中收集不同帖子的链接,然后通过进入解析每个帖子的标题他们的目标页面重用这些收集的链接。虽然内容是静态的,但我想知道 pyppeteer 在这种情况下是如何工作的。

我尝试将 main() 函数中的 browser 变量提供给 fetch()browse_all_links() 函数,以便我可以一遍又一遍地重用同一个浏览器。

我目前的做法:

import asyncio
from pyppeteer import launch

url = "https://stackoverflow.com/questions/tagged/web-scraping"

async def fetch(page,url):
    await page.goto(url)
    linkstorage = []
    await page.waitForSelector('.summary .question-hyperlink')
    elements = await page.querySelectorAll('.summary .question-hyperlink')
    for element in elements:
        linkstorage.append(await page.evaluate('(element) => element.href', element))
    return linkstorage

async def browse_all_links(page,link):
    await page.goto(link)
    await page.waitForSelector('h1 > a')
    title = await page.querySelectorEval('h1 > a','(e => e.innerText)')
    print(title)

async def main():
    browser = await launch(headless=False,autoClose=False)
    [page] = await browser.pages()
    links = await fetch(page,url)
    tasks = [await browse_all_links(page,url) for url in links]
    await asyncio.gather(*tasks)

if __name__ == '__main__':
    asyncio.run(main())

上述脚本获取了一些标题,但在执行过程中的某个时间点出现以下错误:

Possible to select <a> with specific text within the quotes?
Crawler Runs Too Slow
How do I loop a list of ticker to scrape balance sheet info?
How to retrive the url of searched video from youtbe using python
VBA-JSON to import data from all pages in one table
Is there an algorithm that detects semantic visual blocks in a webpage?
find_all only scrape the last value

#ERROR STARTS

Future exception was never retrieved
future: <Future finished exception=NetworkError('Protocol error (Runtime.releaseObject): Cannot find context with specified id')>
pyppeteer.errors.NetworkError: Protocol error (Runtime.releaseObject): Cannot find context with specified id
Future exception was never retrieved

【问题讨论】:

  • 我看到你正在获取href。这可能不完整url,即它可能是/contact 而不是http://www.example.com/contact。在前面的案例中没有指定协议,因此我怀疑它会引发错误。
  • 你错了@Vishnudev。当任何浏览器模拟器发挥作用时,大多数情况下检索到的 url 都是完整的,就像我在这个案例中看到的那样。
  • 哦,好吧。我只是怀疑。如果链接工作正常,那么我不知道为什么会这样。
  • 我从来没有听说过这个工具包,但我看到的第一个谷歌结果似乎很相关。以this 评论开头。
  • @robots.txt 为什么要使用asyncio 标签?已经存在 python-asyncio 标签,包含 2000 多个问题。

标签: python web-scraping puppeteer pyppeteer python-asyncio


【解决方案1】:

由于这个问题发布已经两天了,但还没有人回答,我将借此机会解决这个问题 觉得可能对你有帮助。

  • 有 15 个链接,但你只得到 7 个,这可能是 websockets 失去连接,页面无法访问

  • 列表理解

tasks = [await browse_all_links(page,url) for url in links] 这个列表有什么期望?如果成功,它将是一个列表 无元素。所以你的下一行代码会报错!

  • 解决方案

    将 websockets 7.0 降级到 websockets 6.0

    去掉这行代码await asyncio.gather(*tasks)

    我使用的是 python 3.6,所以我不得不更改最后一行代码。 如果您使用的是我认为您正在使用的 python 3.7,则不需要更改它

import asyncio
from pyppeteer import launch

url = "https://stackoverflow.com/questions/tagged/web-scraping"

async def fetch(page,url):
    await page.goto(url)
    linkstorage = []
    await page.waitForSelector('.summary .question-hyperlink')
    elements = await page.querySelectorAll('.summary .question-hyperlink')
    for element in elements:
        linkstorage.append(await page.evaluate('(element) => element.href', element))
    return linkstorage

async def browse_all_links(page,link):
    await page.goto(link)
    await page.waitForSelector('h1 > a')
    title = await page.querySelectorEval('h1 > a','(e => e.innerText)')
    print(title)
async def main():
    browser = await launch(headless=False,autoClose=False)
    [page] = await browser.pages()
    links = await fetch(page,url)
    tasks = [await browse_all_links(page,url) for url in links]
    #await asyncio.gather(*tasks)
    await browser.close()
if __name__ == '__main__':
    #asyncio.run(main())
    asyncio.get_event_loop().run_until_complete(main())
  • 输出

(testenv) C:\Py\pypuppeteer1>python stack3.py Scrapy Shell response.css 返回一个空数组 Scrapy 实时爬虫 为什么我在使用 get 请求读取数据时得到 KeyError? Scrapy蜘蛛无法根据args重新定义custom_settings 在 Splash UI 中使用 Lua 的自定义 JS 脚本 有人可以解释一下这段代码为什么以及如何工作[搁置] 如何从字符串列表中提取所需数据? Scrapy CrawlSpider 单页爬取规则 当搜索查询没有时,如何抓取带有搜索栏结果的网页 出现在网址中 嵌套for循环不断重复 获取除标签列表之外的所有标签 BeautifulSoup 使用 Python 和 webbot 获取当前 URL 如何登录网站并发送数据 无法将值附加到列。出现错误 IndexError: list index out of ra 恩 NextSibling.Innertext 不起作用。 “对象不支持此属性”

【讨论】:

  • 您的解决方案似乎正在运行,但运行不一致。当我尝试几次时,脚本在最后一个或倒数第二个结果抛出 pyppeteer.errors.TimeoutError: Navigation Timeout Exceeded: 30000 ms exceeded. 之前卡住了。您建议我不要删除最后一行代码。这条线是你的意思await asyncio.gather(*tasks) 不删除吗?最后,我真的不知道如何降级websockets 7.0 to websockets 6.0。顺便说一句,你怎么知道我使用的是 python 3.7?谢谢。
  • 不,你删除 await asyncio.gather(*tasks) 并告诉我。
  • asyncio.run(main()) 仅适用于 python 3.7 或更高版本。您在测试中使用了这行代码,这就是为什么我猜我可能使用的是 python 3.7
  • 我给你反馈时没有使用await asyncio.gather(*tasks)。我可以不只使用try/except 子句来处理该错误吗?但是,我不知道如何在异步模式中使用错误处理程序。顺便说一句,是否有必要将 websockets 7.0 降级到 websockets 6.0?如果是那怎么办?非常感谢。
  • 我使用的是 python 3.6,对我来说有必要将 websockets 7 降级到 6。试一试。 python -m uninstall websockets 然后python -m install websockets== 6.0
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多