首页 > 解决方案 > 获取html动态内容python3

问题描述

我想从网站获取部分 html 动态内容,我可以在“检查元素”中看到此内容,但在“查看源代码”中看不到。我尝试使用 BeautifulSoup 和 selenium 库但没有成功,因为在加载页面后我需要按一些屏幕按钮来加载内容。

例如,在网站http://play.typeracer.com中,我可以加载其 html 源代码,但无法加载在网页上按“练习”后显示的内容。(表格和文字)

希望我是明确的,感谢您的关注

标签: pythonhtmlpython-3.x

解决方案


这是使用 Selenium 和 Firefox 的解决方案:

  1. 打开浏览器窗口并导航到 url
  2. 等待练习链接出现
  3. 提取包含部分文本的所有 span 元素
  4. 创建输出字符串。如果第一个单词只有一个字母,则只有 2 个 span 元素。如果单词有多个字母,则将有 3 个 span 元素。
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    
    url = 'http://play.typeracer.com/'
    browser = webdriver.Firefox()
    browser.get(url)
    
    try:  # waiting till link is loaded
        element = WebDriverWait(browser, 30).until(
            EC.presence_of_element_located((By.LINK_TEXT, 'Practice')))
    finally:  # link loaded -> click it
        element.click()
    
    try:  # wait till text is loaded
        WebDriverWait(browser, 30).until(
            EC.presence_of_element_located((By.XPATH, '//span[@unselectable="on"]')))
    finally:  # extract text 
        spans = browser.find_elements_by_xpath('//span[@unselectable="on"]')
        if len(spans) == 2:  # first word has only one letter
            text = f'{spans[0].text} {spans[1].text}'
        elif len(spans) == 3:  # first word has more than one letter
            text = f'{spans[0].text}{spans[1].text} {spans[2].text}'
        else:
            text = ' '.join([span.text for span in spans])
            print('special case that is not handled yet: {text}')
    
    
    print(text)
    >>> 'Scissors cuts paper. Paper covers rock. Rock crushes lizard. Lizard poisons Spock. Spock smashes scissors. Scissors decapitates lizard. Lizard eats paper. Paper disproves Spock. Spock vaporizes rock. And as it always has, rock crushes scissors.'
    

    更新

    以防万一您还想在之后自动输入;)

    try:
        txt_input = WebDriverWait(browser, 30).until(
            EC.presence_of_element_located((By.XPATH,
                '//input[@class="txtInput" and @autocorrect="off"]')))
    finally:
        for letter in text:
            txt_input.send_keys(letter)
    

    阻塞的原因try:... finally: ...是我们必须等到内容加载完毕——这有时需要相当长的时间。


    推荐阅读