【问题标题】:Can't get all the links connected to a hashtag from a lazy loading webpage无法从延迟加载网页获取连接到主题标签的所有链接
【发布时间】:2019-07-13 18:11:06
【问题描述】:

我用 python 和 selenium 创建了一个脚本来滚动到延迟加载网页的底部并从那里解析内容。我正在尝试从 instagram 获取连接到主题标签的所有链接。那里有大约 475 个结果,但我目前的尝试只得到了 38 个。

我创建的脚本可以滚动到该页面的底部,但在大约 475 个结果中我仍然得到 38 个结果。

Link to that webpage

到目前为止,我已经尝试过:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

tag = '#baltimorepizza'

hash_url = 'https://www.instagram.com/explore/tags/{}/'

def scroll_to_get_more():
    check_height = driver.execute_script("return document.body.scrollHeight;")

    while True:
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        try:
            wait.until(lambda driver: driver.execute_script("return document.body.scrollHeight;")  > check_height)
            check_height = driver.execute_script("return document.body.scrollHeight;") 
        except TimeoutException:
             break

def get_links(tag):
    driver.get(hash_url.format(tag.strip("#").lower()))
    scroll_to_get_more()
    total_links = [item.get_attribute("href") for item in wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,'.kIKUG > a')))]
    print("Total link scraped:",len(total_links))

if __name__ == '__main__':
    driver = webdriver.Chrome()
    wait = WebDriverWait(driver,10)
    get_links(tag)
    driver.quit()

如何从 instagram 获取与该特定主题标签相关的所有链接?

【问题讨论】:

  • 在执行 findElement 后滚动之前是否加载了链接?
  • 在滚动过程中添加链接时,我得到了 437 个链接。但是,这样做时我无法达到 475 个链接。

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


【解决方案1】:

和@KunduK一样,我只能收集437,所以我想知道这是否是正确的数字,也许你需要登录才能看到剩余的..?

你只得到了大约 38 个,因为页面不会一次渲染 DOM 中的整个代码。因此,即使您滚动,您也查询了数据,但并非所有数据都可以访问,只有当您滚动回它时(视图中的图像)。

这里的解决方案将在滚动时获取数据。 我们将首先滚动到底部,并确保使用您的方法 scroll_to_get_more 进行所有查询以加载图像。

然后我们将从上到下开始scraping,所以我们需要一直滚动到顶部使用:

def scroll_to_header():
    el = driver.find_element_by_tag_name("header")
    driver.execute_script("arguments[0].scrollIntoView();", el)

您的 get_links 方法现在将如下所示:

def get_links(tag):
    driver.get(hash_url.format(tag.strip("#").lower()))
    scroll_to_get_more()
    scroll_to_header()
    total_links = []
    current_len = 0
    new_len = -1
    while current_len != new_len:
        current_len = len(total_links)
        try:
            links = []
            elements = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,'.Nnq7C.weEfm [href]')))
            for el in elements:
                if el.get_attribute('href') not in total_links:
                    links.append(el.get_attribute('href'))
            total_links.extend(links)
        except StaleElementReferenceException:
            continue
        if len(elements):
            driver.execute_script("arguments[0].scrollIntoView();", el)
        new_len = len(total_links)

    print("Total link scraped:", len(total_links))

基本上,在每次查询之后,我们都会滚动到最后一个元素,这将在 DOM 中加载下一个图像。

另外,我认为您的滚动方法是我得到 437(滚动和缺少元素)的原因。所以我实现了一个新方法,它使用微调器作为滚动元素,而不是页面的高度。两者都是有效的,但我认为这个更快(见下面的结果):

def scroll_to_get_more():
    while True:
        try:
            spinner = driver.find_element_by_css_selector('.By4nA')
            driver.execute_script("arguments[0].scrollIntoView();", spinner)
        except StaleElementReferenceException:
            continue
        except NoSuchElementException:
            break

以上滚动方式的输出:

Total link scraped: 437
Query took: 23.520002755

使用滚动方法输出:

Total link scraped: 437
Query took: 42.685470925

造成时间差的主要原因是,一旦页面不再需要滚动,你总是会休眠 10 秒。

【讨论】:

    猜你喜欢
    • 2021-08-08
    • 2017-09-30
    • 1970-01-01
    • 2013-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多