我需要编写一个自动抓取工具,该工具可以处理由JavaScript渲染的网站(例如YouTube),或者只是在HTML的某个位置使用一些JavaScript来生成某些内容(例如生成版权年份),然后下载其HTML源没有意义,因为它不是最终的代码(用户将看到的代码)。
我将Python与Selenium和WebDriver结合使用,以便可以在给定的网站上执行JavaScript。为此,我的代码是:
def execute_javascript_on_website(self, js_command):
driver = webdriver.Firefox(firefox_options = self.webdriver_options, executable_path = os.path.dirname(os.path.abspath(__file__)) + '/executables/geckodriver')
driver.get(self.url)
try:
return driver.execute_script(js_command)
except Exception as exception_message:
pass
finally:
driver.close()
js_command = "return document.documentElement.outerHTML;"
处。
通过此代码,我可以获取源代码,但不能获取呈现的代码。我可以做js_command = "return document;"
(就像在控制台中所做的那样),但是我会得到<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="5a784804-f623-3041-9840-03f13ce83f53", element="585b43a1-f3b2-1e4a-b348-4ddaf2944550")>
具有HTML的对象,但是不可能从中删除它。
有人知道如何使用Selenium来获取JavaScript呈现的HTML(最好是字符串形式)的方法吗?还是其他可以做到的技术?
PS 。:我也尝试了WebDriver等待,但这没有帮助,我仍然获得了HTML和未重编JavaScript。
PPS:我需要获取带有HTML渲染的完整HTML代码(整个html标签)(例如,在浏览器检查器中进行检查时)。或者至少要获取已经呈现JavaScript的网站的DOM。
答案 0 :(得分:0)
driver.execute_script("return document.getElementsByTagName('html')[0].innerHTML")
答案 1 :(得分:0)
我已经研究过了,我不得不承认@Rumpelstiltskin Koriat的答案中的JavaScript是有效的。当前年份存在于返回的HTML字符串中,并放置在script标记之后(如@pguardiario所述,它必须在此处,因为它只是HTML标记)。我还发现,在这种情况下,通过脚本标签提供简单的JavaScript代码,甚至不需要WebriverWait即可获取具有渲染JavaScript代码的HTML字符串。显然,我已经设法忽略了我急切想要的JavaScript字符串渲染。
我还发现(如@Corey Goldberg所建议的那样),Selenium方法也很好用,同时看起来比纯JavaScript行driver.find_element_by_tag_name('html').get_attribute('innerHTML')
更好。然后,它返回一个字符串,而不返回任何webelement。
另一方面,当需要刮除Angular支持的网站的整个HTML时,有必要在理想情况下(至少在YouTube网站中)找到带有id="content"
的标签(然后将此位置包括在代码稍后使用的所有XPath的开头-模拟我们有一个完整的HTML)或其中一个标记。这里也不需要WebriverWait。
但是,当仅定位HTML标记或 yt-app 标记或带有id="content"
的标记之外的任何其他标记时,则会返回带有未渲染JavaScript的HTML。 Angular生成的网站中的HTML与Agular自己的标签(浏览器显然会忽略)混合在一起。