最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python使用Scrapy抓取和解析網(wǎng)頁數(shù)據(jù)的方法

 更新時(shí)間:2026年05月11日 09:25:19   作者:yuanpan  
很多 Python 初學(xué)者學(xué)完基礎(chǔ)語法后,都會(huì)遇到一個(gè)很實(shí)際的問題:怎么把網(wǎng)頁里的數(shù)據(jù)穩(wěn)定地提取下來,變成自己能處理的結(jié)構(gòu)化數(shù)據(jù),Scrapy 是 Python 生態(tài)里非常經(jīng)典的爬蟲框架,本文給大家介紹了Python使用Scrapy抓取和解析網(wǎng)頁數(shù)據(jù)的方法,需要的朋友可以參考下

引言

很多 Python 初學(xué)者學(xué)完基礎(chǔ)語法后,都會(huì)遇到一個(gè)很實(shí)際的問題:怎么把網(wǎng)頁里的數(shù)據(jù)穩(wěn)定地提取下來,變成自己能處理的結(jié)構(gòu)化數(shù)據(jù)?

如果你只是偶爾抓一個(gè)頁面,用 requests + BeautifulSoup 當(dāng)然可以;但當(dāng)你想抓取多個(gè)頁面、自動(dòng)跟進(jìn)鏈接、統(tǒng)一清洗字段、導(dǎo)出成 JSON 或 CSV,甚至把數(shù)據(jù)存進(jìn)數(shù)據(jù)庫時(shí),Scrapy 會(huì)明顯更省事。

Scrapy 是 Python 生態(tài)里非常經(jīng)典的爬蟲框架。它不只是“下載網(wǎng)頁源碼”,而是把發(fā)請求、收響應(yīng)、解析數(shù)據(jù)、跟蹤鏈接、導(dǎo)出結(jié)果、去重、限速、日志管理這一整套流程都組織好了。

這篇文章面向新手,目標(biāo)很明確:

  • 讓你理解 Scrapy 是什么
  • 帶你從零創(chuàng)建一個(gè) Scrapy 項(xiàng)目
  • 學(xué)會(huì)抓取網(wǎng)頁、解析字段、翻頁采集、導(dǎo)出數(shù)據(jù)
  • 告訴你 Scrapy 除了抓文章標(biāo)題之外,還能做什么

學(xué)完后,你至少能獨(dú)立寫出一個(gè)基礎(chǔ)可用的網(wǎng)頁數(shù)據(jù)采集腳本。

1. Scrapy 是什么

Scrapy 是一個(gè)用于抓取網(wǎng)站并提取結(jié)構(gòu)化數(shù)據(jù)的 Python 框架。

你可以把它理解成一個(gè)專門為“網(wǎng)頁采集”準(zhǔn)備好的工程化工具箱。相比只寫一個(gè)簡單腳本,Scrapy 的優(yōu)勢在于它已經(jīng)幫你解決了很多重復(fù)問題,比如:

  • 請求調(diào)度
  • 并發(fā)抓取
  • 自動(dòng)跟蹤鏈接
  • 頁面解析
  • 數(shù)據(jù)導(dǎo)出
  • 日志輸出
  • 重試與超時(shí)
  • 去重和限速

也就是說,Scrapy 更適合做“持續(xù)抓取”和“多頁面采集”,而不只是一次性的實(shí)驗(yàn)代碼。

2. Scrapy 適合哪些場景

對新手來說,最適合先用 Scrapy 解決的,通常是下面這些任務(wù):

  • 抓取資訊站點(diǎn)的標(biāo)題、鏈接、發(fā)布時(shí)間
  • 采集商品列表頁中的名稱、價(jià)格、銷量、詳情頁地址
  • 批量抓取博客、論壇、文檔站中的內(nèi)容摘要
  • 采集招聘網(wǎng)站中的崗位名稱、城市、薪資范圍
  • 采集分頁數(shù)據(jù)并導(dǎo)出成 JSON、CSV、Excel 可再處理的數(shù)據(jù)

如果你的目標(biāo)是“從很多網(wǎng)頁里提取重復(fù)結(jié)構(gòu)的數(shù)據(jù)”,Scrapy 基本就是合適的工具。

3. Scrapy 和requests + BeautifulSoup有什么區(qū)別

很多新手會(huì)問:我已經(jīng)會(huì) requestsBeautifulSoup,為什么還要學(xué) Scrapy?

可以這樣理解:

  • requests 負(fù)責(zé)發(fā)請求
  • BeautifulSoup 負(fù)責(zé)解析 HTML
  • Scrapy 則把請求、解析、調(diào)度、導(dǎo)出、翻頁、日志這些能力打包成了一個(gè)框架

如果只是抓 1 個(gè)頁面,requests + BeautifulSoup 更輕量。

如果要抓幾十頁、幾百頁,或者想要把項(xiàng)目組織得更清晰、可復(fù)用、可擴(kuò)展,Scrapy 往往更合適。

4. 安裝 Scrapy

先確保你已經(jīng)安裝了 Python。然后直接執(zhí)行:

pip install scrapy

安裝完成后,可以檢查版本:

scrapy version

如果命令能正常輸出版本信息,說明 Scrapy 已經(jīng)安裝成功。

5. 創(chuàng)建第一個(gè) Scrapy 項(xiàng)目

Scrapy 通常不是單文件腳本的寫法,而是按項(xiàng)目組織。

先創(chuàng)建項(xiàng)目:

scrapy startproject myspider

進(jìn)入項(xiàng)目目錄:

cd myspider

你會(huì)看到類似這樣的結(jié)構(gòu):

myspider/
├── scrapy.cfg
└── myspider/
    ├── __init__.py
    ├── items.py
    ├── middlewares.py
    ├── pipelines.py
    ├── settings.py
    └── spiders/

幾個(gè)最常見的文件先記?。?/p>

  • spiders/:放爬蟲代碼
  • items.py:定義要采集的數(shù)據(jù)字段
  • pipelines.py:對采集結(jié)果做清洗、保存、去重等處理
  • settings.py:配置請求頭、并發(fā)、延時(shí)、導(dǎo)出編碼等

剛開始你不需要把每個(gè)文件都學(xué)透,先會(huì)寫 spiders/ 里的爬蟲就夠了。

6. 先寫一個(gè)最小可運(yùn)行的爬蟲

下面我們用一個(gè)經(jīng)典練習(xí)站點(diǎn) https://quotes.toscrape.com/ 來演示。這個(gè)站點(diǎn)專門給爬蟲教程使用,頁面結(jié)構(gòu)簡單,很適合新手練手。

spiders 目錄下新建文件 quotes_spider.py

import scrapy


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = ["https://quotes.toscrape.com/"]

    def parse(self, response):
        for quote in response.css("div.quote"):
            yield {
                "text": quote.css("span.text::text").get(),
                "author": quote.css("small.author::text").get(),
                "tags": quote.css("div.tags a.tag::text").getall(),
            }

這段代碼先不要急著背,先理解它在做什么:

  • name 是爬蟲名字,后面運(yùn)行時(shí)要用
  • start_urls 是起始頁面列表
  • parse() 是默認(rèn)解析函數(shù)
  • response.css(...) 用 CSS 選擇器定位網(wǎng)頁元素
  • yield 把采集到的一條數(shù)據(jù)交給 Scrapy

7. 運(yùn)行爬蟲并查看結(jié)果

在項(xiàng)目根目錄執(zhí)行:

scrapy crawl quotes

如果你想把結(jié)果直接導(dǎo)出成 JSON:

scrapy crawl quotes -O quotes.json

導(dǎo)出成 CSV:

scrapy crawl quotes -O quotes.csv

這一步非常重要,因?yàn)楹芏嘈率值谝淮谓佑| Scrapy 時(shí),會(huì)突然意識到:原來我不用自己手寫文件保存邏輯,Scrapy 已經(jīng)幫我做好了。

8.response到底是什么

parse(self, response) 里,response 就是服務(wù)器返回的頁面響應(yīng)對象。

你經(jīng)常會(huì)用到這些能力:

response.url
response.status
response.text
response.css(...)
response.xpath(...)

比如:

def parse(self, response):
    print(response.url)
    print(response.status)

你可以把它理解成:請求完成后,Scrapy 把網(wǎng)頁內(nèi)容和相關(guān)信息都封裝進(jìn)了 response,供你繼續(xù)解析。

9. 用 CSS 選擇器提取數(shù)據(jù)

Scrapy 對 CSS 選擇器支持很好,新手建議優(yōu)先學(xué)這個(gè)。

還是看剛才那段代碼:

quote.css("span.text::text").get()
quote.css("small.author::text").get()
quote.css("div.tags a.tag::text").getall()

這里有兩個(gè)高頻方法:

  • .get():取第一個(gè)匹配結(jié)果
  • .getall():取所有匹配結(jié)果并返回列表

常見寫法:

response.css("title::text").get()
response.css("a::attr(href)").getall()
response.css("img::attr(src)").getall()

如果頁面里你想抓的是文本,就常用 ::text;如果你想抓鏈接或圖片地址,就常用 ::attr(...)。

10. 也可以用 XPath

Scrapy 同樣支持 XPath:

quote.xpath('.//span[@class="text"]/text()').get()
quote.xpath('.//small[@class="author"]/text()').get()
quote.xpath('.//div[@class="tags"]/a[@class="tag"]/text()').getall()

那到底該學(xué) CSS 還是 XPath?

我的建議是:

  • 入門先用 CSS,語法更短
  • 遇到復(fù)雜層級、兄弟節(jié)點(diǎn)、條件匹配時(shí),再補(bǔ) XPath

只會(huì)其中一種,也已經(jīng)能做很多事。

11. 學(xué)會(huì)翻頁抓取

單頁采集只是開始,真正實(shí)用的場景通常都要翻頁。

quotes.toscrape.com 首頁底部有“下一頁”鏈接,我們可以繼續(xù)跟進(jìn):

import scrapy


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = ["https://quotes.toscrape.com/"]

    def parse(self, response):
        for quote in response.css("div.quote"):
            yield {
                "text": quote.css("span.text::text").get(),
                "author": quote.css("small.author::text").get(),
                "tags": quote.css("div.tags a.tag::text").getall(),
            }

        next_page = response.css("li.next a::attr(href)").get()
        if next_page:
            yield response.follow(next_page, callback=self.parse)

這里最關(guān)鍵的一句是:

yield response.follow(next_page, callback=self.parse)

它的意思是:繼續(xù)請求下一頁,請求完成后仍然交給 parse() 處理。

這就是 Scrapy 很舒服的地方之一。你不需要自己手工拼接完整鏈接,也不用自己寫復(fù)雜的循環(huán)控制。

12. 定義 Item,讓數(shù)據(jù)結(jié)構(gòu)更清晰

直接 yield {} 當(dāng)然可以,但項(xiàng)目稍微大一點(diǎn)之后,定義 Item 會(huì)更規(guī)范。

先修改 items.py

import scrapy


class QuoteItem(scrapy.Item):
    text = scrapy.Field()
    author = scrapy.Field()
    tags = scrapy.Field()

然后在爬蟲中使用:

import scrapy
from myspider.items import QuoteItem


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = ["https://quotes.toscrape.com/"]

    def parse(self, response):
        for quote in response.css("div.quote"):
            item = QuoteItem()
            item["text"] = quote.css("span.text::text").get()
            item["author"] = quote.css("small.author::text").get()
            item["tags"] = quote.css("div.tags a.tag::text").getall()
            yield item

Item 的好處是字段邊界更清楚,后面寫清洗邏輯、保存邏輯時(shí)也更統(tǒng)一。

13. 用 Pipeline 清洗數(shù)據(jù)

很多網(wǎng)頁抓下來之后,并不是馬上就能直接用。常見問題包括:

  • 文本前后有空格
  • 某些字段為空
  • 日期格式不統(tǒng)一
  • 同一條數(shù)據(jù)重復(fù)出現(xiàn)

這時(shí)就可以把清洗邏輯放進(jìn) pipelines.py

例如:

class MyspiderPipeline:
    def process_item(self, item, spider):
        if item.get("text"):
            item["text"] = item["text"].strip()

        if item.get("author"):
            item["author"] = item["author"].strip()

        item["tags"] = [tag.strip() for tag in item.get("tags", [])]
        return item

然后去 settings.py 啟用它:

ITEM_PIPELINES = {
    "myspider.pipelines.MyspiderPipeline": 300,
}

新手可以先記住一句話:Spider 負(fù)責(zé)抓,Pipeline 負(fù)責(zé)洗。

14. 常見配置項(xiàng):新手最該先知道哪些

Scrapy 很強(qiáng),但默認(rèn)并不是“想怎么抓就怎么抓”。你至少應(yīng)該知道下面幾個(gè)配置項(xiàng)。

14.1 設(shè)置請求標(biāo)識

有些網(wǎng)站會(huì)根據(jù)請求頭判斷請求來源。你可以在 settings.py 里設(shè)置:

USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0 Safari/537.36"

14.2 控制抓取速度

不要對目標(biāo)網(wǎng)站發(fā)太快的請求。新手階段建議至少加一點(diǎn)延時(shí):

DOWNLOAD_DELAY = 1

14.3 關(guān)閉robots.txt限制前先理解規(guī)則

很多教程會(huì)寫:

ROBOTSTXT_OBEY = False

但你需要先知道這意味著什么。robots.txt 是網(wǎng)站聲明抓取規(guī)則的地方。是否遵守,要根據(jù)你的使用場景、目標(biāo)站點(diǎn)規(guī)則和合規(guī)要求來判斷。新手不要一上來就默認(rèn)無視規(guī)則。

14.4 導(dǎo)出中文時(shí)避免亂碼

如果你要導(dǎo)出中文 JSON,經(jīng)常會(huì)加:

FEED_EXPORT_ENCODING = "utf-8"

這能減少導(dǎo)出文件中文亂碼的問題。

15. 一個(gè)更像真實(shí)項(xiàng)目的完整示例

下面給你一個(gè)稍完整一點(diǎn)的爬蟲,把抓取、翻頁和字段提取放在一起:

import scrapy


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    allowed_domains = ["quotes.toscrape.com"]
    start_urls = ["https://quotes.toscrape.com/"]

    def parse(self, response):
        for quote in response.css("div.quote"):
            yield {
                "text": quote.css("span.text::text").get(default="").strip(),
                "author": quote.css("small.author::text").get(default="").strip(),
                "tags": quote.css("div.tags a.tag::text").getall(),
                "detail_url": response.urljoin(
                    quote.css("span a::attr(href)").get(default="")
                ),
            }

        next_page = response.css("li.next a::attr(href)").get()
        if next_page:
            yield response.follow(next_page, callback=self.parse)

這個(gè)版本已經(jīng)覆蓋了初學(xué)者最常用的幾個(gè)動(dòng)作:

  • 進(jìn)入起始頁
  • 遍歷列表塊
  • 提取文本、作者、標(biāo)簽、詳情鏈接
  • 繼續(xù)翻頁

16. 新手最容易踩的坑

剛學(xué) Scrapy 時(shí),下面這些問題非常常見:

16.1 選擇器寫對了,但取不到數(shù)據(jù)

原因可能包括:

  • 頁面結(jié)構(gòu)和你想的不一樣
  • 內(nèi)容在 JavaScript 運(yùn)行后才出現(xiàn)
  • 你選中的節(jié)點(diǎn)層級不對
  • 屬性名或類名寫錯(cuò)

先做兩件事:

  • 在瀏覽器開發(fā)者工具里重新檢查元素
  • scrapy shell 網(wǎng)址 進(jìn)入交互環(huán)境測試選擇器

例如:

scrapy shell https://quotes.toscrape.com/

進(jìn)入后可以直接測試:

response.css("title::text").get()

這是定位問題最快的方法之一。

16.2 頁面明明能打開,但 Scrapy 抓不到完整內(nèi)容

這通常是因?yàn)槟繕?biāo)頁面的數(shù)據(jù)是前端 JavaScript 動(dòng)態(tài)渲染出來的,而 Scrapy 默認(rèn)抓到的是原始 HTML 響應(yīng)。

這時(shí)你有幾種思路:

  • 先在瀏覽器網(wǎng)絡(luò)面板里找真實(shí)接口,直接抓接口數(shù)據(jù)
  • 配合 scrapy-playwright 處理需要渲染的頁面
  • 對確實(shí)只依賴靜態(tài) HTML 的站點(diǎn),優(yōu)先直接用 Scrapy

對新手來說,先學(xué)會(huì)抓靜態(tài)頁面,再處理動(dòng)態(tài)頁面,學(xué)習(xí)曲線會(huì)平很多。

16.3 導(dǎo)出的數(shù)據(jù)重復(fù)

原因往往是:

  • 翻頁邏輯寫錯(cuò)
  • 同一個(gè)鏈接被多次跟進(jìn)
  • 詳情頁和列表頁重復(fù)產(chǎn)出同一條記錄

解決思路通常是:

  • 檢查 next_page 邏輯
  • 用唯一字段去重
  • 在 Pipeline 中做重復(fù)判斷

17. Scrapy 除了抓網(wǎng)頁標(biāo)題,還能做什么

很多新手誤以為 Scrapy 只能“抓文章標(biāo)題”。其實(shí)它能做的事情遠(yuǎn)不止這些。

17.1 采集結(jié)構(gòu)化業(yè)務(wù)數(shù)據(jù)

比如:

  • 商品名稱、價(jià)格、庫存、評分
  • 招聘崗位、地點(diǎn)、經(jīng)驗(yàn)要求、薪資區(qū)間
  • 博客標(biāo)題、作者、發(fā)布時(shí)間、標(biāo)簽
  • 課程名稱、章節(jié)、講師、簡介

17.2 批量跟進(jìn)詳情頁

很多網(wǎng)站首頁只給列表摘要,真正的詳細(xì)信息在詳情頁里。Scrapy 很適合這種“列表頁拿鏈接,再進(jìn)入詳情頁補(bǔ)字段”的流程。

17.3 構(gòu)建數(shù)據(jù)清洗流水線

抓取不是終點(diǎn)。你可以在 Scrapy 里順手做:

  • 文本清洗
  • 字段標(biāo)準(zhǔn)化
  • 去重
  • 時(shí)間格式轉(zhuǎn)換
  • 金額單位統(tǒng)一

17.4 導(dǎo)出到多種格式

Scrapy 原生就支持把數(shù)據(jù)導(dǎo)出為:

  • JSON
  • CSV
  • JSON Lines
  • XML

如果你自己再擴(kuò)展 Pipeline,還可以保存到:

  • MySQL
  • PostgreSQL
  • MongoDB
  • Redis
  • Elasticsearch

17.5 做定時(shí)采集任務(wù)

Scrapy 項(xiàng)目很適合接入定時(shí)任務(wù),比如每天抓一次新聞、每小時(shí)抓一次價(jià)格、每周抓一次崗位變化。它不只是“寫完跑一次”的腳本,也可以發(fā)展成長期運(yùn)行的數(shù)據(jù)采集工程。

18. 學(xué) Scrapy 時(shí)要有的正確認(rèn)知

Scrapy 很強(qiáng),但它不是萬能的。

你要早點(diǎn)建立這幾個(gè)認(rèn)知:

  • 它擅長靜態(tài)頁面和結(jié)構(gòu)化采集
  • 它不負(fù)責(zé)替你繞過網(wǎng)站風(fēng)控
  • 它不保證所有 JavaScript 頁面都能直接抓
  • 它是工程框架,不只是幾行演示代碼

也就是說,學(xué)習(xí) Scrapy 的重點(diǎn)不是死記 API,而是建立一個(gè)完整思路:

  1. 找頁面結(jié)構(gòu)
  2. 寫選擇器
  3. 提取字段
  4. 跟進(jìn)分頁或詳情頁
  5. 清洗和保存結(jié)果

只要這個(gè)流程打通,后面你抓不同網(wǎng)站時(shí)變化的主要只是選擇器和字段,而不是整個(gè)方法 論。

19. 給新手的學(xué)習(xí)路線

如果你剛開始學(xué) Scrapy,我建議按下面順序練習(xí):

  1. 先抓單頁標(biāo)題、鏈接、文本
  2. 再練列表頁循環(huán)提取
  3. 再加翻頁
  4. 再進(jìn)入詳情頁補(bǔ)充字段
  5. 再學(xué)習(xí) Item、Pipeline、Settings
  6. 最后再接觸動(dòng)態(tài)渲染頁面和數(shù)據(jù)庫存儲(chǔ)

不要一上來就挑戰(zhàn)特別復(fù)雜的網(wǎng)站。先把簡單站點(diǎn)做通,成就感會(huì)高很多,理解也更扎實(shí)。

20. 總結(jié)

如果你想系統(tǒng)學(xué)習(xí) Python 爬蟲,Scrapy 是非常值得投入時(shí)間的框架。

它的價(jià)值不只是“能抓網(wǎng)頁”,而是把網(wǎng)頁采集這件事從零散腳本提升成了一個(gè)更規(guī)范、更穩(wěn)定、可擴(kuò)展的工程流程。對新手來說,一旦你學(xué)會(huì)了:

  • 創(chuàng)建項(xiàng)目
  • 編寫 Spider
  • 用 CSS 或 XPath 解析字段
  • 實(shí)現(xiàn)翻頁抓取
  • 用 Pipeline 清洗數(shù)據(jù)
  • 導(dǎo)出結(jié)果

你就已經(jīng)具備了獨(dú)立完成基礎(chǔ)網(wǎng)頁數(shù)據(jù)采集任務(wù)的能力。

最后提醒一句:在實(shí)際抓取網(wǎng)站數(shù)據(jù)時(shí),一定要關(guān)注目標(biāo)網(wǎng)站的使用規(guī)則、訪問頻率和合規(guī)要求。技術(shù)能力越強(qiáng),越要有邊界意識。

如果你剛準(zhǔn)備開始動(dòng)手,最推薦的練習(xí)方式就是自己創(chuàng)建一個(gè) Scrapy 項(xiàng)目,抓取 quotes.toscrape.com 這樣的練習(xí)站點(diǎn),把本文里的例子完整跑一遍。只要你親手跑通一次,Scrapy 就不會(huì)再顯得抽象。

以上就是Python使用Scrapy抓取和解析網(wǎng)頁數(shù)據(jù)的方法的詳細(xì)內(nèi)容,更多關(guān)于Python Scrapy抓取和解析網(wǎng)頁數(shù)據(jù)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

南平市| 日照市| 贵港市| 清徐县| 南涧| 祥云县| 西乡县| 灵石县| 中超| 加查县| 利辛县| 京山县| 晋中市| 西丰县| 崇义县| 咸宁市| 宜川县| 义乌市| 六盘水市| 资中县| 钟山县| 洛隆县| 星座| 石屏县| 大田县| 平利县| 蒙阴县| 丹寨县| 鄂伦春自治旗| 赣州市| 东宁县| 永平县| 昆山市| 杭州市| 安达市| 永德县| 宕昌县| 桂林市| 庆阳市| 陆丰市| 沂源县|