使用带有 javascript 页面的 python 请求
Posted
技术标签:
【中文标题】使用带有 javascript 页面的 python 请求【英文标题】:Using python Requests with javascript pages 【发布时间】:2014-12-11 03:51:26 【问题描述】:我正在尝试将 Requests 框架与 python (http://docs.python-requests.org/en/latest/) 一起使用,但我试图访问的页面使用 javascript 来获取我想要的信息。
我曾尝试在网上搜索解决方案,但事实上我使用关键字 javascript 进行搜索,我得到的大部分内容是如何使用 javascript 语言进行抓取。
有没有在使用 javascript 的页面上使用 requests 框架?
【问题讨论】:
【参考方案1】:好消息:现在有一个支持 javascript 的请求模块:https://pypi.org/project/requests-html/
from requests_html import HTMLSession
session = HTMLSession()
r = session.get('http://www.yourjspage.com')
r.html.render() # this call executes the js in the page
作为奖励,我认为这是 BeautifulSoup
,所以你可以做类似的事情
r.html.find('#myElementID').text
如您所愿返回 HTML 元素的内容。
【讨论】:
不应该是r.html.find('#myElementID').text
吗?还有r = session.get('http://www.yourjspage.com')
?
解决菲尔指出的问题后,我仍然收到“RuntimeError:无法在现有事件循环中使用 HTMLSession。请改用 AsyncHTMLSession。”
@KubaFYI 是的,他们可以开始把东西移到 python3 上
@HuckIt 为了解决这个问题,您将导入AsyncHTMLSession
而不是HTMLSession
,渲染将使用await session.get(url).result().arender()
调用。我刚遇到这个问题,这就是我解决它的方法。
正如其文档requests.readthedocs.io/projects/requests-html/en/latest/…requests_html 中所写,在后台使用Chromium。所以它是由类似请求的包装器控制的 Chromium 浏览器。【参考方案2】:
您将不得不发出与 javascript 发出的相同请求(使用请求库)。您可以使用任意数量的工具(包括 Chrome 和 Firefox 中内置的工具)来检查来自 javascript 的 http 请求,并且只需自己从 Python 发出此请求。
【讨论】:
所以没有办法让请求使用javascript。 不,Requests 是一个 http 库。它无法运行 javascript。 我使用 Chrome 工具调试网站并查找 Javascript 调用的内容。您可以在github.com/719Ben/myCUinfo-API 看到我创建的结果 到目前为止这是最好的。您还可以获得漂亮的 JSON,因此更容易获取数据【参考方案3】:虽然 Selenium 看起来很诱人且很有用,但它有一个无法解决的主要问题:性能。通过计算浏览器所做的每一件事,您将需要更多的功能。即使是 PhantomJS 也无法与简单的请求竞争。我建议您仅在真正需要单击按钮时才使用 Selenium。如果你只需要javascript,我推荐PyQt(查看https://www.youtube.com/watch?v=FSH77vnOGqU学习)。
但是,如果你想使用 Selenium,我推荐 Chrome 而不是 PhantomJS。许多用户在使用 PhantomJS 时遇到网站根本无法在 Phantom 中运行的问题。 Chrome 也可以是无头(非图形)的!
首先,确保您已经安装了 ChromeDriver,Selenium 依赖它来使用 Google Chrome。
然后,通过在 URL chrome://settings/help 中检查以确保您拥有 60 或更高版本的 Google Chrome
现在,您需要做的就是以下代码:
from selenium.webdriver.chrome.options import Options
from selenium import webdriver
chrome_options = Options()
chrome_options.add_argument("--headless")
driver = webdriver.Chrome(chrome_options=chrome_options)
如果您不知道如何使用 Selenium,这里有一个快速概述:
driver.get("https://www.google.com") #Browser goes to google.com
寻找元素: 使用 ELEMENTS 或 ELEMENT 方法。示例:
driver.find_element_by_css_selector("div.logo-subtext") #Find your country in Google. (singular)
driver.find_element(s)_by_css_selector(css_selector) # 匹配此 CSS 选择器的每个元素
driver.find_element(s)_by_class_name(class_name) # 每个元素都有下面的类
driver.find_element(s)_by_id(id) # 每个元素的ID如下
driver.find_element(s)_by_link_text(link_text) # 每一个都有完整的链接文本
driver.find_element(s)_by_partial_link_text(partial_link_text) # 每一个都有部分链接文本。
driver.find_element(s)_by_name(name) #name=argument 的每个元素
driver.find_element(s)_by_tag_name(tag_name) # 每一个带有标签名参数的元素
好的!我找到了一个元素(或元素列表)。但是我现在该怎么办?
以下是您可以对元素执行的方法elem:
elem.tag_name # 可以返回按钮。 elem.get_attribute("id") # 返回一个元素的ID。 elem.text # 元素的内部文本。 elem.clear() # 清除文本输入。 elem.is_displayed() # 可见元素为真,不可见元素为假。 elem.is_enabled() # 启用输入为真,否则为假。 elem.is_selected() # 这个单选按钮或复选框元素是否被选中? elem.location # 一个字典,表示屏幕上元素的 X 和 Y 位置。 elem.click() # 点击elem. elem.send_keys("thelegend27") # 在elem中输入thelegend27(对文本输入有用) elem.submit() # 提交elem参与的表单。特殊命令:
driver.back() # 点击返回按钮。 driver.forward() # 点击前进按钮。 driver.refresh() # 刷新页面。 driver.quit() # 关闭浏览器,包括所有标签页。 foo = driver.execute_script("return 'hello';") # 执行 javascript(可以获取返回值!)【讨论】:
【参考方案4】:它是 pyppeteer 或 smth 的包装器? :( 我认为它有些不同
@property
async def browser(self):
if not hasattr(self, "_browser"):
self._browser = await pyppeteer.launch(ignoreHTTPSErrors=not(self.verify), headless=True, args=self.__browser_args)
return self._browser
【讨论】:
【参考方案5】:使用 Selenium 或启用 jQuery 的请求很慢。在网站检查浏览器上的 JavaScript 并获取该 cookie 并将其用于您的每个请求后,找出生成哪个 cookie 会更有效。
在一个示例中,它通过以下 cookie 工作:
在此示例中检查 javascript 后生成的 cookie 是“cf_clearance”。 所以只需创建一个会话。 像这样更新 cookie 和标头:
s = requests.Session()
s.cookies["cf_clearance"] = "cb4c883efc59d0e990caf7508902591f4569e7bf-1617321078-0-150"
s.headers.update(
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"
)
s.get(url)
而且你不需要像 Selenium 这样的 JavaScript 解决方案。这是更快更有效的方式。打开浏览器后只需要获取一次cookie即可。
【讨论】:
以上是关于使用带有 javascript 页面的 python 请求的主要内容,如果未能解决你的问题,请参考以下文章
提交时保留的带有 Javascript 表单数据的客户端 html 页面[关闭]
如何使用 Javascript 发送带有 windows.location.href 的参数
我们可以在 Node JS 应用程序中使用带有 ejs(嵌入式 javascript)的 socket.io 而不是 html 页面吗?