簡體   English   中英

Python BeautifulSoup 和 Selenium 沒有抓取完整的 html

[英]Python BeautifulSoup & Selenium not scraping full html

初學者網絡爬蟲在這里。 我的練習任務很簡單:收集/統計玩家在過去 50 場比賽中的 Pokemon 使用情況,例如在此頁面上 為此,我計划使用包含 Pokemon 名稱的 Pokemon 的圖像 url(在<img>標簽中,由<span></span>包裹)。 從 Chrome 檢查看起來像這樣<img alt="Played pokemon" srcset="/_next/image?url=%2FSprites%2Ft_Square_Snorlax.png&amp;w=96&amp;q=75 1x, /_next/image?url=%2FSprites%2Ft_Square_Snorlax.png&amp;w=256&amp;q=75 2x" ...

1)單獨使用 Beautiful Soup 並不能獲得我需要的圖像的 html:

import requests
from bs4 import BeautifulSoup as bs

r = requests.get('https://uniteapi.dev/p/%E3%81%BB%E3%81%B0%E3%81%A1')
wp_player = bs(r.content)
wp_player.select('span img')

2)使用 Selenium 彌補了 BeautifulSoup 遺漏的一些東西:

from bs4 import BeautifulSoup as bs
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

url = "https://uniteapi.dev/p/%E3%81%BB%E3%81%B0%E3%81%A1"
options = Options()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
driver = webdriver.Chrome(options=options)
driver.get(url)
page = driver.page_source
driver.quit()

soup = bs(page, 'html.parser')
soup.select('span img')

但它給了我看起來像這樣的鏈接: <img alt="Played pokemon" data-nimg="fixed" decoding="async" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"

我在這里有什么誤解? 我感興趣的網站沒有公共 API,盡管它的名字。 任何幫助深表感謝。

這是在網站完全加載之前抓取網站時的常見問題。 您要做的基本上是等待頁面完全加載您需要的圖像。 您有兩個選擇, 隱式等待顯式等待圖像元素被加載。

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options

url = r"https://uniteapi.dev/p/%E3%81%BB%E3%81%B0%E3%81%A1"
options = Options()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
driver = webdriver.Chrome(executable_path='./chromedriver.exe', options=options)
driver.get(url)
WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '[alt="Played pokemon"]'))) # EXPLICIT WAIT
driver.implicitly_wait(10) # IMPLICIT WAIT

pokemons = driver.find_elements_by_css_selector('[alt="Played pokemon"]')
for element in pokemons:
    print(element.get_attribute("src"))

您必須選擇其中一個,但最好在嘗試訪問它們的值之前顯式等待元素呈現。

輸出:
pokemons = driver.find_elements_by_css_selector('[alt="Played pokemon"]') https://uniteapi.dev/_next/image?url=%2FSprites%2Ft_Square_Tsareena.png&w=256&q=75 https://uniteapi.dev/_next /image?url=%2FSprites%2Ft_Square_Tsareena.png&w=256&q=75 https://uniteapi.dev/_next/image?url=%2FSprites%2Ft_Square_Snorlax.png&w=256&q=75 https://uniteapi.dev/_next/image ?url=%2FSprites%2Ft_Square_Snorlax.png&w=256&q=75 https://uniteapi.dev/_next/image?url=%2FSprites%2Ft_Square_Snorlax.png&w=256&q=75 https://uniteapi.dev/_next/image?url =%2FSprites%2Ft_Square_Snorlax.png&w=256&q=75 https://uniteapi.dev/_next/image?url=%2FSprites%2Ft_Square_Snorlax.png&w=256&q=75

您的解決方法不起作用,因為您正在向頁面發出獲取請求,該頁面在初始狀態下獲取 html 值,此時所有 DOM 元素仍未呈現。

原因是該站點使用所謂的 Ajax 通過 JavaScript 動態加載神奇寶貝。

您可以做的一件事實際上是在調試器中觀察網絡選項卡並查找包含數據的 url,如果您可以直接調用返回您正在查找的數據的 url。

很多時候,當網絡抓取時,你可以這樣做,它會以更序列化的格式返回數據。

否則,您可以按照 Sac 的回答中提到的方法進行操作,然后等待數據完全加載。 通過檢查一個元素是否已經加載,或者只是硬編碼一個睡眠調用,這不太干凈。

雖然不是答案,但我們特意在代碼中加入了防刮設備。 如果您不嘗試抓取我們的網站並在我們的不和諧中與我們交談,我將不勝感激。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM