Python爬虫框架之Scrapy详解和单页爬取教程传送门:
今天我们直接来看实战,爬取糗事百科所有段子,先来看看我们获取到的结果:
控制台
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条数据已经全部获取到本地。