python - 使用 Python 抓取 Javascript 创建的动态内容

标签 python arrays python-3.x web-scraping beautifulsoup

我想使用 python 脚本废弃由 javascript 函数创建的 DIV 内容。我已经尝试过使用 BS4 并且通过这样做我无法获得动态数据。相反,它只显示源代码。

示例代码:

import requests
from bs4 import BeautifulSoup

URL = "https://rawgit.com/skysoft999/tableauJS/master/example.html"
r = requests.get(URL)

soup = BeautifulSoup(r.content, 'html5lib')


for row in soup.findAll('div', attrs = {'class':'quote'}):
    print(row)


print(soup.prettify())

示例 HTML 源代码位于 Pastebin

要提取的样本数据:

enter image description here

最佳答案

初始 HTML 不包含您要抓取的数据,这就是为什么只使用 BeautifulSoup是不足够的。您可以使用 Selenium 加载页面然后抓取内容。

代码:

import json

from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException

html = None
url = 'http://demo-tableau.bitballoon.com/'
selector = '#dataTarget > div'
delay = 10  # seconds

browser = webdriver.Chrome()
browser.get(url)

try:
    # wait for button to be enabled
    WebDriverWait(browser, delay).until(
        EC.element_to_be_clickable((By.ID, 'getData'))
    )
    button = browser.find_element_by_id('getData')
    button.click()

    # wait for data to be loaded
    WebDriverWait(browser, delay).until(
        EC.presence_of_element_located((By.CSS_SELECTOR, selector))
    )
except TimeoutException:
    print('Loading took too much time!')
else:
    html = browser.page_source
finally:
    browser.quit()

if html:
    soup = BeautifulSoup(html, 'lxml')
    raw_data = soup.select_one(selector).text
    data = json.loads(raw_data)

    import pprint
    pprint.pprint(data)

输出:

[[{'formattedValue': 'Atlantic', 'value': 'Atlantic'},
  {'formattedValue': '6/26/2010 3:00:00 AM', 'value': '2010-06-26 03:00:00'},
  {'formattedValue': 'ALEX', 'value': 'ALEX'},
  {'formattedValue': '16.70000', 'value': '16.7'},
  {'formattedValue': '-84.40000', 'value': '-84.4'},
  {'formattedValue': '30', 'value': '30'}],
  ...
]

代码假定按钮最初被禁用:<button id="getData" onclick="getUnderlyingData()" disabled>Get Data</button>并且数据不会自动加载,而是由于单击了按钮。因此,您需要删除此行:setTimeout(function(){ getUnderlyingData(); }, 3000); .

您可以在此处找到示例的工作演示:http://demo-tableau.bitballoon.com/ .

关于python - 使用 Python 抓取 Javascript 创建的动态内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49939123/

相关文章:

python - Scrapy Spider 不返回任何信息

Python 随机样本生成器(适用于庞大的人口规模)

arrays - 为什么我不能检查我的数组数组是否包含特定数组?

javascript - 在 jQuery 中分割 URL 路径并获取其中的一部分

python - Python 3 中小数到 2 位的钱

python-3.x - 匹配字符串中同时出现的单词

python - 如何限制用户可以上传到我的表单的文件类型?

python - 如何将文本文件中的数字读取为列表中的数字?

javascript - 返回数组的属性

python - 检查单词之间的编辑次数