【发布时间】:2021-05-19 05:27:20
【问题描述】:
我需要创建一个服务器,通过从指定站点获取抓取的数据,我可以向其发出 REST 请求。
例如这样的网址:
http://myip/scraper?url=www.exampe.com&token=0
我必须抓取一个内置 javascript 的网站,该网站可以识别它是由真实浏览器还是无头浏览器打开的。
唯一的选择是 selenium 或 pyppeteer 和一个 virtualDisplay。
我目前使用 selenium 和 FastAPI,但它不是一个有很多请求的可用解决方案。对于每个请求 chrome 的打开和关闭,这都会大大延迟响应并使用大量资源。
使用 pyppeteer async,您可以在同一个浏览器实例上同时打开多个选项卡,从而减少响应时间。但这可能会在多个选项卡之后导致其他问题。
我正在考虑创建一个浏览器实例池,在该池上将各种请求划分为puppeteer-cluster。
但到目前为止我还没有弄清楚。
我目前正在为浏览器尝试此代码:
import json
from pyppeteer import launch
from strings import keepa_storage
class Browser:
async def __aenter__(self):
self._session = await launch(headless=False, args=['--no-sandbox', "--disable-gpu", '--lang=it',
'--disable-blink-features=AutomationControlled'], autoClose=False)
return self
async def __aexit__(self, *err):
self._session = None
async def fetch(self, url):
page = await self._session.newPage()
page_source = None
try:
await page.goto("https://example.com/404")
for key in keepa_storage:
await page.evaluate(
"window.localStorage.setItem('{}',{})".format(key, json.dumps(example_local_storage.get(key))))
await page.goto(url)
await page.waitForSelector('#tableElement')
page_source = await page.content()
except TimeoutError as e:
print(f'Timeout for: {url}')
finally:
await page.close()
return page_source
这个请求的代码:
async with Browser() as http:
source = await asyncio.gather(
http.fetch('https://example.com')
)
但我不知道如何为多个服务器请求重用相同的浏览器会话
【问题讨论】:
-
就在几天前,我遇到了类似的问题。我们通过使用 Manager-Worker 形成来解决它。经理维护工人队列的地方。每个工作人员基本上都是无头模式下的 chromedriver 实例。一旦经理收到请求,它就会派出一名工作人员来消费该项目。成功完成后,它将工作人员放回队列,否则重新启动工作人员并将其放回队列。
-
这个想法理论上还不错,但总是为每个chromedriver实例只打开一个链接。我想尝试为每个浏览器实例打开更多的 url。你有你工作的例子吗?
-
我们可以在每个 Chromedriver 中打开多个标签页。我不能分享整个代码。对此感到抱歉。过段时间我会分享这两个类的整体界面。
-
谢谢,同时我试着看看怎么做。
标签: python selenium fastapi pyppeteer