无法从网页获取动态生成的内容

时间:2018-07-08 15:11:25

标签: python python-3.x selenium selenium-webdriver web-scraping

我已经用python用selenium编写了一个脚本,以获取位于网页右下角标题business summary下的p(位于Company profile标签内)。该网页是高度​​动态的,因此我认为使用浏览器模拟器。我创建了一个CSS选择器,如果我直接从该网页复制html elements并在本地尝试,则可以解析摘要。出于某种原因,当我在下面的脚本中尝试使用相同的选择器时,它不会成功。它会引发timeout exception错误。我该如何获取?

这是我的尝试:

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
from selenium.common.exceptions import TimeoutException

link = "https://in.finance.yahoo.com/quote/AAPL?p=AAPL"

def get_information(driver, url):
    driver.get(url)
    item = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "[id$='-QuoteModule'] p[class^='businessSummary']")))
    driver.execute_script("arguments[0].scrollIntoView();", item)
    print(item.text)

if __name__ == "__main__":
    driver = webdriver.Chrome()
    wait = WebDriverWait(driver, 20)
    try:
        get_information(driver,link)
    finally:
        driver.quit()

3 个答案:

答案 0 :(得分:3)

最初似乎没有“业务摘要”块,但在向下滚动页面后生成。请尝试以下解决方案:

from selenium.webdriver.common.keys import Keys

def get_information(driver, url):
    driver.get(url)
    driver.find_element_by_tag_name("body").send_keys(Keys.END)
    item = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "[id$='-QuoteModule'] p[class^='businessSummary']")))
    print(item.text)

答案 1 :(得分:1)

您必须向下滚动两次页面,直到该元素出现:

    /* change character set to utf8 */
    if (!$db->set_charset("utf8")) {
        printf("Error loading character set utf8: %s\n", $mysqli->error);
        exit();
    } 
    else {
        //printf("Current character set: %s\n", $mysqli->character_set_name());
    }

如果仅滚动一次,则由于某种原因(至少对我而言),它将无法正常工作。我认为这取决于窗口尺寸,在较小的窗口上,您滚动的比在较大的窗口上要多。

答案 2 :(得分:1)

这是使用请求并处理页面中已存在的JSON数据的简单得多的方法。如果可能,我还建议始终使用请求。这可能需要一些额外的工作,但最终结果会更加可靠/清洁。您还可以进一步介绍我的示例,并解析JSON以直接使用它(您需要清理文本才能使它成为有效的JSON)。在我的示例中,我只是使用split,这样做的速度更快,但是在执行更复杂的操作时可能会导致问题。

import requests

from lxml import html

url = 'https://in.finance.yahoo.com/quote/AAPL?p=AAPL'
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'}
r = requests.get(url, headers=headers)

tree = html.fromstring(r.text)

data= [e.text_content() for e in tree.iter('script') if 'root.App.main = ' in e.text_content()][0]
data = data.split('longBusinessSummary":"')[1]
data = data.split('","city')[0]

print (data)