溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python異步加載怎么爬取圖片

發布時間:2021-11-25 09:13:51 來源:億速云 閱讀:302 作者:iii 欄目:大數據
# Python異步加載怎么爬取圖片

## 引言

在當今的Web開發中,異步加載(Asynchronous Loading)已成為提升用戶體驗的主流技術。對于爬蟲開發者而言,這卻帶來了新的挑戰——傳統的同步請求無法直接獲取異步加載的內容(如圖片懶加載、動態渲染等)。本文將詳細介紹如何用Python突破異步加載限制,高效爬取網頁圖片。

---

## 一、理解異步加載機制

### 1.1 什么是異步加載?
異步加載指網頁通過JavaScript動態請求數據并更新DOM,無需刷新整個頁面。常見場景包括:
- 圖片懶加載(Lazy Load):滾動到視口才加載圖片
- 無限滾動(Infinite Scroll):滾動到底部加載新內容
- AJAX動態請求:點擊按鈕后加載數據

### 1.2 識別異步圖片
打開瀏覽器開發者工具(F12):
- **Network面板**:過濾`Img`類型,觀察圖片請求觸發時機
- **XHR/Fetch請求**:部分圖片通過API接口返回
- **滾動測試**:向下滾動時是否出現新圖片請求

---

## 二、技術方案對比

| 方案                | 優點                    | 缺點                          |
|---------------------|-------------------------|-------------------------------|
| 1. 直接解析HTML     | 簡單快速                | 無法獲取異步內容              |
| 2. 模擬瀏覽器       | 可執行JS                | 資源消耗大                    |
| 3. 分析API接口      | 高效直接                | 需要逆向工程                  |
| 4. 混合方案         | 兼顧效率與完整性        | 實現復雜度較高                |

---

## 三、實戰代碼演示

### 3.1 方案一:Selenium模擬瀏覽器
適用于需要完整渲染頁面的場景

```python
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import requests
import os

def download_image(url, filename):
    response = requests.get(url, stream=True)
    with open(filename, 'wb') as f:
        for chunk in response.iter_content(1024):
            f.write(chunk)

def crawl_with_selenium(url, save_dir):
    # 初始化瀏覽器
    options = webdriver.ChromeOptions()
    options.add_argument('--headless')  # 無頭模式
    driver = webdriver.Chrome(options=options)
    
    try:
        driver.get(url)
        # 模擬滾動觸發懶加載
        last_height = driver.execute_script("return document.body.scrollHeight")
        while True:
            driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
            time.sleep(2)  # 等待加載
            new_height = driver.execute_script("return document.body.scrollHeight")
            if new_height == last_height:
                break
            last_height = new_height
        
        # 提取圖片
        images = driver.find_elements(By.TAG_NAME, 'img')
        os.makedirs(save_dir, exist_ok=True)
        
        for idx, img in enumerate(images):
            src = img.get_attribute('src')
            if src and 'http' in src:
                download_image(src, f"{save_dir}/image_{idx}.jpg")
                
    finally:
        driver.quit()

# 示例使用
crawl_with_selenium("https://example.com/lazy-load", "downloaded_images")

3.2 方案二:逆向API接口

適用于通過XHR請求獲取數據的網站

import requests
import json
import re

def extract_image_urls(api_url):
    headers = {
        'User-Agent': 'Mozilla/5.0',
        'X-Requested-With': 'XMLHttpRequest'
    }
    response = requests.get(api_url, headers=headers)
    data = response.json()
    
    # 使用正則從JSON中提取圖片URL(根據實際API結構調整)
    urls = []
    json_str = json.dumps(data)
    pattern = r'https?://[^"\s]+?\.(jpg|png|webp)'
    urls = re.findall(pattern, json_str, re.I)
    return list(set(urls))  # 去重

3.3 方案三:Playwright高級控制

新一代瀏覽器自動化工具,比Selenium更高效

from playwright.sync_api import sync_playwright

def crawl_with_playwright(url):
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)
        page = browser.new_page()
        page.goto(url)
        
        # 等待特定元素出現
        page.wait_for_selector('img.lazy-loaded')
        
        # 獲取所有圖片元素
        images = page.query_selector_all('img')
        for img in images:
            src = img.get_attribute('src')
            print(f"Found image: {src}")
        
        browser.close()

四、關鍵問題解決方案

4.1 處理動態參數

部分網站使用加密參數保護API:

# 示例:解析加密參數
import hashlib

def generate_signature(params):
    secret = 'website_secret_key'
    raw = f"{params}{secret}".encode()
    return hashlib.md5(raw).hexdigest()

4.2 繞過反爬機制

  • 隨機User-Agent:使用fake_useragent
  • IP輪換:結合代理池(如Scrapy+Scrapy-ProxyPool)
  • 請求限速:添加隨機延遲

4.3 存儲優化

# 使用異步存儲提高IO效率
import aiohttp
import aiofiles

async def async_download(url, path):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as resp:
            async with aiofiles.open(path, 'wb') as f:
                await f.write(await resp.read())

五、性能優化建議

  1. 并發控制:使用asyncio+aiohttp實現異步請求 “`python import asyncio from aiohttp import ClientSession

async def fetch_all(urls): async with ClientSession() as session: tasks = [] for url in urls: task = asyncio.create_task(fetch(url, session)) tasks.append(task) return await asyncio.gather(*tasks)


2. **緩存機制**:對已下載圖片建立MD5校驗
3. **斷點續傳**:記錄已成功下載的URL列表

---

## 結語

爬取異步加載圖片需要根據目標網站的具體實現選擇合適方案。對于簡單懶加載,Selenium/Playwright即可解決;對于復雜API接口,需要結合網絡抓包和逆向分析。隨著Web技術的演進,爬蟲開發者需要持續學習新的反爬對策和技術方案。

> **注意事項**:爬取前務必檢查網站的`robots.txt`文件,遵守版權法規和相關服務條款。

(全文約1680字,實際字數可能因代碼格式略有差異)

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女