【问题标题】:Scraping a dynamic website with Selenium/BeautifulSoup使用 Selenium/BeautifulSoup 抓取动态网站
【发布时间】:2019-09-29 21:37:39
【问题描述】:

我正在尝试使用 Selinium 和 Beutifulsoup 从网站上抓取 cmets。我试图从中抓取的网站是由 Javascript 动态生成的,这与我在所见教程中所学的内容相差无几(我对 javascript 不太熟悉)。到目前为止,我最好的工作解决方案是:

browser = webdriver.Chrome(executable_path=chromedriver_path)
browser.get('https://nationen.ebcomments.dk/embed/stream?asset_id=7627366')
def load_data():
    time.sleep(1) # The site needs to load
    browser.execute_script("document.querySelector('#stream > div.talk-stream-tab-container.Stream__tabContainer___2trkn > div:nth-child(2) > div > div > div > div > div:nth-child(3) > button').click()") # Click on load more comments button

htmlSource = browser.page_source
soup = BeautifulSoup(browser.page_source, 'html.parser')
load_data() # i should call this few times to load all comments, but in this example i only do it once.
for text in soup.findAll(class_="talk-plugin-rich-text-text"):
    print(text.get_text(), "\n") # Print the comments

它可以工作 - 但它很慢,而且我确信有更好的解决方案,特别是如果我想用 cmets 抓取数百篇文章。

我认为所有 cmets 都采用 JSON 格式(我查看了网络下的 Chromes 开发选项卡,我可以看到有一个响应包含带有注释的 JSON - 参见图片)。然后我尝试使用 SeliniumRequest 来获取数据,但完全不确定我在做什么,而且它不起作用。它说 "b'POST body missing. 你忘了使用 body-parser 中间件吗?'"。 也许我可以从 cmets API 获取 JSON,但我不确定它是否可能?

from seleniumrequests import Chrome
chromedriver_path = 'C:/chromedriver.exe'
webdriver = Chrome(executable_path=chromedriver_path)
response = webdriver.request('POST', 'https://nationen.ebcomments.dk/api/v1/graph/ql/', data={"assetId": "7627366", "assetUrl": "", "commentId": "","excludeIgnored": "false","hasComment": "false", "sortBy": "CREATED_AT", "sortOrder": "DESC"})

【问题讨论】:

    标签: javascript python selenium web-scraping beautifulsoup


    【解决方案1】:

    如果只有你所追求的 cmets,那么下面的实现应该能让你到达那里:

    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
    
    link = "https://nationen.ebcomments.dk/embed/stream?asset_id=7627366"
    
    with webdriver.Chrome() as driver:
        wait = WebDriverWait(driver,10)
        driver.get(link)
        while True:
            try:
                wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,".talk-load-more > button"))).click()
            except Exception: break
    
        for item in wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,"[data-slot-name='commentContent'] > .CommentContent__content___ZGv1q"))):
            print(item.text)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-31
      • 1970-01-01
      相关资源
      最近更新 更多