天天看點

Scrapy翻頁爬取糗事百科所有段子後,我總結出的...

Python爬蟲架構之Scrapy詳解和單頁爬取教程傳送門:

Scrapy爬取B站小姐姐入門教程,結果萬萬沒想到!

Scrapy翻頁爬取糗事百科所有段子後,我總結出的...

今天我們直接來看實戰,爬取糗事百科所有段子,先來看看我們擷取到的結果:

Scrapy翻頁爬取糗事百科所有段子後,我總結出的...

控制台

Scrapy翻頁爬取糗事百科所有段子後,我總結出的...

json檔案

1. 确定目标:打開糗事百科-段子欄下。我們此行目标資料有5個。作者姓名、作者等級、段子内容、點贊數和評論數。

首頁連結:

https://www.qiushibaike.com/text/
           
Scrapy翻頁爬取糗事百科所有段子後,我總結出的...

2. 建立工程。我們使用指令

scrapy startproject qiushibaike
           
Scrapy翻頁爬取糗事百科所有段子後,我總結出的...

3. 然後我們使用指令 

scrapy genspider spider_bk www.qiushibaike.com/text/
           

建立一個spider_bk.py的python檔案來實作具體的爬蟲。

Scrapy翻頁爬取糗事百科所有段子後,我總結出的...

4. 接下來我們先來實作我們的實體類items.py檔案。我們要擷取的資料有如下五個。

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy

class QiushibaikeItem(scrapy.Item):
    # define the fields for your item here like:
    # 作者
    author = scrapy.Field()

    # 作者等級
    level = scrapy.Field()

    # 内容
    context = scrapy.Field()

    # 贊同人數
    star = scrapy.Field()

    # 評論人數
    comment = scrapy.Field()

           

5. 我們先在爬蟲檔案spider_bk.py實作單頁資料的擷取。

import scrapy
from qiushibaike.items import QiushibaikeItem

class SpiderBkSpider(scrapy.Spider):
    name = 'spider_bk'
    allowed_domains = ['www.qiushibaike.com/text/page/1/']
    start_urls = ['https://www.qiushibaike.com/text/']


    def parse(self, response):

        # 執行個體化方法
        item = QiushibaikeItem()

        # 擷取目前頁面的所有的div
        divs = response.xpath("//div[@class='col1 old-style-col1']/div")

        for div in divs:
            item['author'] = div.xpath('./div[@class="author clearfix"]/a/h2/text()').get().strip()      # 作者
            item['level'] = div.xpath('./div[@class="author clearfix"]/div/text()').get()        # 作者等級

            content = div.xpath(".//div[@class='content']//text()").getall()
            content = " ".join(content).strip()                     # 内容
            item['context'] = content

            item['star'] = div.xpath('./div/span/i/text()').get()                               # 贊同人數
            item['comment'] = div.xpath('./div/span/a/i/text()').get()                           # 評論人數

            yield item
           

6. 我們将擷取到的資料存入到pipelines.py的糗事百科.json檔案中,為了友善看到資料我們再儲存之前先将資料列印出來。

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html


# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
import json

class QiushibaikePipeline:
    def process_item(self, item, spider):
        print(item['author'])
        print(item['level'])
        print(item['context'])
        print(item['star'])
        print(item['comment'])

        # 儲存檔案到本地
        with open('./糗事百科.json', 'a+', encoding='utf-8') as f:
            lines = json.dumps(dict(item), ensure_ascii=False) + '\n'
            f.write(lines)

        return item
           

7. 我們再建立一個main方法,将資料在控制台列印出來。就避免了每次都在指令行寫指令的麻煩了。

from scrapy import cmdline
cmdline.execute('scrapy crawl spider_bk -s LOG_FILE=all.log'.split())
           

8. 接下來我們在setting.py中打開如下設定:

from fake_useragent import UserAgent

BOT_NAME = 'qiushibaike'

SPIDER_MODULES = ['qiushibaike.spiders']
NEWSPIDER_MODULE = 'qiushibaike.spiders'


# Obey robots.txt rules
ROBOTSTXT_OBEY = False

# Override the default request headers:
DEFAULT_REQUEST_HEADERS = {
   'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
   'User-Agent': str(UserAgent().random),
}

ITEM_PIPELINES = {
    'qiushibaike.pipelines.QiushibaikePipeline': 300,
}

           

9.最後一步我們執行寫好main方法來列印單頁資料到控制台。

Scrapy翻頁爬取糗事百科所有段子後,我總結出的...

可以看到單頁資料已經成功的擷取到。我們可以看到糗事百科段子總共有13頁,我們的目标就是這13頁的全部資料。

Scrapy翻頁爬取糗事百科所有段子後,我總結出的...

10. 我們在爬蟲檔案spider_bk中加一個循環來擷取全部的資料。

    def start_requests(self):
        # 擷取翻頁URL
        for page in range(1, 13 + 1):
            url = 'https://www.qiushibaike.com/text/page/{}/'.format(str(page))  # 提取翻頁連結
            yield scrapy.Request(url, callback=self.parse)
           

再次執行main方法,13頁325條資料已經全部擷取到本地。

Scrapy翻頁爬取糗事百科所有段子後,我總結出的...