使用带有javascript页面的python请求

biw*_*biw 32 python web-scraping python-requests

我正在尝试使用python的请求框架(http://docs.python-requests.org/en/latest/),但我试图访问的页面使用javascript来获取我想要的信息.

我试图在网上搜索一个解决方案,但事实上我正在搜索关键字javascript,我得到的大部分内容是如何使用javascript语言.

无论如何使用请求框架与使用javascript的页面?

sbe*_*rry 28

您将不得不使用javascript创建相同的请求(使用Requests库).您可以使用任意数量的工具(包括Chrome和Firefox中内置的工具)来检查来自javascript的http请求,并自行从Python发出此请求.

  • 不,请求是一个http库.它无法运行javascript. (8认同)
  • 你在哪里看到了什么工具你用它来找到它?我现在正在尝试这个,而且我被困住了 (6认同)
  • 本,你能发布你的解决方案吗? (5认同)
  • 所以没有办法让请求使用javascript. (2认同)
  • 我使用Chrome工具调试网站并查找Javascript调用的内容.您可以在https://github.com/719Ben/myCUinfo-API上看到我创建的结果 (2认同)

Lil*_*aco 20

虽然Selenium可能看起来很诱人且有用,但它有一个无法解决的主要问题:性能.通过计算浏览器所做的每件事,您将需要更多的功能.甚至PhantomJS也不会与简单的请求竞争.我建议您在真正需要单击按钮时才使用Selenium.如果你只需要javascript,我推荐PyQt(请查看https://www.youtube.com/watch?v=FSH77vnOGqU来学习它).

但是,如果您想使用Selenium,我建议使用Chrome over PhantomJS.很多用户都遇到PhantomJS的问题,其中一个网站根本无法在Phantom中运行.Chrome也可以是无头(非图形)!

首先,请确保您安装了ChromeDriver,Selenium依赖它来使用Google Chrome.

然后,通过在网址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)
Run Code Online (Sandbox Code Playgroud)

如果你不知道如何使用Selenium,这里有一个快速概述:

driver.get("https://www.google.com") #Browser goes to google.com
Run Code Online (Sandbox Code Playgroud)

查找元素:使用ELEMENTS或ELEMENT方法.例子:

driver.find_element_by_css_selector("div.logo-subtext") #Find your country in Google. (singular)
Run Code Online (Sandbox Code Playgroud)
  • 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#可以返回a中的按钮.
  • elem.get_attribute("id")#返回元素的ID.
  • elem.text#元素的内部文本.
  • elem.clear()#清除文本输入.
  • elem.is_displayed()#True表示可见元素,False表示不可见元素.
  • elem.is_enabled()#True表示启用的输入,否则为False.
  • elem.is_selected()#是否选中了这个单选按钮或复选框元素?
  • elem.location#表示屏幕上元素的X和Y位置的字典.
  • elem.click()#点击elem.
  • elem.send_keys("thelegend27")#将thelegend27输入elem(对文本输入有用)
  • elem.submit()#提交elem参与的表格.

特殊命令:

  • driver.back()#单击"后退"按钮.
  • driver.forward()#单击"前进"按钮.
  • driver.refresh()#刷新页面.
  • driver.quit()#关闭浏览器,包括所有选项卡.
  • foo = driver.execute_script("return'hello';")#执行javascript(可以返回值!)


小智 12

好消息:现在有一个支持javascript的请求模块:https : //pypi.org/project/requests-html/

from requests_html import HTMLSession

session = HTMLSession()

r = session('http://www.yourjspage.com')

r.html.render()  # this call executes the js in the page
Run Code Online (Sandbox Code Playgroud)

BeautifulSoup我认为,这样做可以带来额外的好处,因此您可以执行以下操作

r.find('#myElementID').text
Run Code Online (Sandbox Code Playgroud)

它将按预期返回HTML元素的内容。

  • @KubaFYI 是的,他们可以开始将东西转移到 python3 (25认同)
  • 在修复 Phil 指出的问题后,我仍然收到“RuntimeError:无法在现有事件循环中使用 HTMLSession。改用 AsyncHTMLSession。” (4认同)
  • @HuckIt为了解决这个问题,您将导入`AsyncHTMLSession`而不是`HTMLSession`,并且将使用`await session.get(url).result().arender()`调用渲染。我刚刚遇到这个问题,这就是我解决它的方法。 (4认同)
  • 不应该是`r.html.find('#myElementID')。text`吗?还有`r = session.get('http://www.yourjspage.com')`? (3认同)
  • 正如其文档 https://requests.readthedocs.io/projects/requests-html/en/latest/#javascript-support requests_html 中所写,在后台使用 Chromium。所以它是由类似请求的包装器控制的 Chromium 浏览器。 (3认同)