需要向下滚动时进行网页抓取

时间:2019-03-05 02:47:31

标签: python web-scraping python-requests

我想在网页https://www.quora.com/topic/Stack-Overflow-4/all_questions下抓取例如前200个问题的标题。我尝试了以下代码:

import requests
from bs4 import BeautifulSoup

url = "https://www.quora.com/topic/Stack-Overflow-4/all_questions"
print("url")
print(url)
r = requests.get(url) # HTTP request
print("r")
print(r)
html_doc = r.text # Extracts the html
print("html_doc")
print(html_doc)
soup = BeautifulSoup(html_doc, 'lxml') # Create a BeautifulSoup object
print("soup")
print(soup)

它给了我一个文本https://pastebin.com/9dSPzAyX。如果我们搜索href='/,我们可以看到html确实包含一些问题的标题。但是,问题在于数量不够。实际上在网页上,用户需要手动向下滚动以触发额外的负载

有人知道我如何模仿程序“向下滚动”以加载页面的更多内容吗?

4 个答案:

答案 0 :(得分:0)

网页上的无限滚动基于Javascript功能。因此,要找出我们需要访问的URL和使用什么参数,我们需要彻底研究页面内部的JS代码,或者最好检查一下您向下滚动页面时浏览器的请求。我们可以使用开发人员工具研究请求。 See example for quora

向下滚动越多,生成的请求越多。因此,现在您的请求将针对该URL而不是普通URL进行,但请记住发送正确的标题和播放负载。

其他更简单的解决方案是使用硒

答案 1 :(得分:0)

我建议使用selenium而不是bs。
selenium可以控制浏览器和解析。例如向下滚动,单击按钮等……

此示例用于向下滚动以获取instagram中的所有喜欢的用户。
https://stackoverflow.com/a/54882356/5611675

答案 2 :(得分:0)

如果仅在“向下滚动”时加载内容,则可能意味着该页面正在使用Javascript动态加载内容。

您可以尝试使用诸如PhantomJS之类的Web客户端来加载页面并在其中执行javascript,并通过注入诸如document.body.scrollTop = sY;Simulate scroll event using Javascript)之类的JS来模拟滚动。

答案 3 :(得分:0)

找不到使用请求的响应。但是您可以使用Selenium。首先在第一次加载时打印出问题的数量,然后发送End键以模拟向下滚动。发送结束键后,您会看到问题数量从20个增加到40个。

我使用driver。隐式等待5秒钟再重新加载DOM,以防脚本在加载DOM之前快速加载。您可以通过将EC与硒一起使用来改善。

此页面每卷加载20个问题。因此,如果您想抓取100个问题,则需要发送5次“结束”键。

要使用下面的代码,您需要安装chromedriver。 http://chromedriver.chromium.org/downloads

    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.common.by import By

    CHROMEDRIVER_PATH = ""
    CHROME_PATH = ""
    WINDOW_SIZE = "1920,1080"

    chrome_options = Options()
    # chrome_options.add_argument("--headless")  
    chrome_options.add_argument("--window-size=%s" % WINDOW_SIZE)
    chrome_options.binary_location = CHROME_PATH
    prefs = {'profile.managed_default_content_settings.images':2}
    chrome_options.add_experimental_option("prefs", prefs)

    url = "https://www.quora.com/topic/Stack-Overflow-4/all_questions"

    def scrape(url, times):

    if not url.startswith('http'):
        raise Exception('URLs need to start with "http"')

    driver = webdriver.Chrome(
    executable_path=CHROMEDRIVER_PATH,
    chrome_options=chrome_options
    )

    driver.get(url)

    counter = 1
    while counter <= times:

        q_list = driver.find_element_by_class_name('TopicAllQuestionsList')
        questions = [x for x in q_list.find_elements_by_xpath('//div[@class="pagedlist_item"]')]
        q_len = len(questions)
        print(q_len)

        html = driver.find_element_by_tag_name('html')
        html.send_keys(Keys.END)

        wait = WebDriverWait(driver, 5)
        time.sleep(5)

        questions2 = [x for x in q_list.find_elements_by_xpath('//div[@class="pagedlist_item"]')]
        print(len(questions2))

        counter += 1

    driver.close()

if __name__ == '__main__':
    scrape(url, 5)