Python爬蟲架構之Scrapy詳解和單頁爬取教程傳送門:
Scrapy爬取B站小姐姐入門教程,結果萬萬沒想到!
今天我們直接來看實戰,爬取糗事百科所有段子,先來看看我們擷取到的結果:
控制台
json檔案
1. 确定目标:打開糗事百科-段子欄下。我們此行目标資料有5個。作者姓名、作者等級、段子内容、點贊數和評論數。
首頁連結:
https://www.qiushibaike.com/text/
2. 建立工程。我們使用指令
scrapy startproject qiushibaike
3. 然後我們使用指令
scrapy genspider spider_bk www.qiushibaike.com/text/
建立一個spider_bk.py的python檔案來實作具體的爬蟲。
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方法來列印單頁資料到控制台。
可以看到單頁資料已經成功的擷取到。我們可以看到糗事百科段子總共有13頁,我們的目标就是這13頁的全部資料。
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條資料已經全部擷取到本地。