无法从延迟加载网页中获取所有与主题标签相关的链接

时间:2019-07-13 18:11:06

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

我已经在python和硒中创建了一个脚本,以滚动到延迟加载网页的底部并从那里解析内容。我正在尝试将所有链接连接到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获取与该特定主题标签相关的所有链接?

1 个答案:

答案 0 :(得分:1)

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

您只得到〜38,因为该页面无法一次呈现DOM中的整个代码。因此,即使您进行了滚动,也查询了数据,但并不是全部可以访问,只有当您滚动回它时(视图中的图像)。

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

然后,我们将从顶部开始到底部开始抓取,因此我们需要使用以下方式一直滚动回到顶部:

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秒。