爬取的初始网址是: https://www.qiushibaike.com/text/page/1/
首先需要创建项目
cd 目录路径进入到对应的目录
然后使用下面的代码进行创建 scrapy 项目
# 项目名: qsbk
scrapy startproject qsbk
进入目录 qsbk , 并使用crawl模版创建爬虫文件
# -t crawl | 使用 crawl模版
# text | 爬虫文件名 执行爬虫的名字
# www.qiushibaike.com | 爬虫允许的域名
scrapy genspider -t crawl text www.qiushibaike.com
进行修改配置文件 settings.py
# ...省略部分代码
# 找到下面一句, 进行复制到下一行, 并把值改为 False
# 是否遵守 robots.txt 的规则
# ROBOTSTXT_OBEY = True
ROBOTSTXT_OBEY = False
# ...省略部分代码
#DOWNLOADER_MIDDLEWARES = {
# 'qsbk.middlewares.QsbkDownloaderMiddleware': 543,
#}
# 找到下面一段, 进行复制到下一行
# 是否启用下载器中间件 (动态ua使用)
DOWNLOADER_MIDDLEWARES = {
'qsbk.middlewares.QsbkDownloaderMiddleware': 543,
}
# ...省略部分代码
# 找到下面一段, 进行复制到下一行
# 使用什么方式进行数据存储
# ITEM_PIPELINES = {
# 'qsbk.pipelines.QsbkPipeline': 300,
# }
ITEM_PIPELINES = {
# 'qsbk.pipelines.QsbkPipeline': 300,
# 这是新增的部分
# 这里是使用 redis 进行存储, 暂时先不用
# 'scrapy_redis.pipelines.RedisPipeline': 400,
}
# ...省略部分代码
# 增加这一句
# 日志是否打印输出
LOG_ENABLED = False
# 分布式配置
# 以下3句是分布式redis需要的
# DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# SCHEDULER_PERSIST = True
进行修改下载器中间件 middlewares.py
from scrapy import signals
# useful for handling different item types with a single interface
from itemadapter import is_item, ItemAdapter
# 在 头部导入库的位置加上这一句
# UserAgent 是为了实现多个网页爬取时使用随机ua
from fake_useragent import UserAgent
# ...省略部分代码
# 找到这一句
class QsbkDownloaderMiddleware:
# 找到下面方法
def process_request(self, request, spider):
# 加上这一句, 修改响应头信息的ua 设置为随机ua
request.headers['User-Agent'] = UserAgent().random
修改爬虫文件 text.py
# 在导入位置加上这一句
# 导入 pyquery 用于页面解析获取数据
from pyquery import PyQuery as pq
# 在爬虫类里面设置这个
start_urls = ['https://www.qiushibaike.com/text/page/1/']
# 加上这一句
redis_key = 'TextSpider:start_urls' # 第一页由redis传入
# 在规则部分设置这两句
rules = (
# Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),
# https://www.qiushibaike.com/text/page/1/
# allow 内使用正则 | \d 表示数字 | + 表示一个或多个
# follow 爬取后是否继续爬
# callback 爬取后交给那个函数或方法处理 使用字符串表示当前对象的某个方法 也可以直接 self.parse_item
Rule(LinkExtractor(allow=r'https://www.qiushibaike.com/text/page/\d+/'), follow=True), # callback='parse_item',
# https://www.qiushibaike.com/article/124906526
Rule(LinkExtractor(allow=r'https://www.qiushibaike.com/article/\d+'), callback='parse_item', follow=False),
)
# 增加这一个方便知道爬了多少
parseIndex = 0
def parse_item(self, response):
u = response.url # response 是响应对象 url是响应的url, 请求的url和响应的url是可能不同的
parseIndex = self.parseIndex # 这就是上面类的 parseIndex
ua = response.request.headers['User-Agent'] # 获取请求的ua 看看是否实现了动态ua
_ = pq(response.text) # 将响应回来的文本放入到 pq对象 获得一个pq实例对象
t = _('title').text() # 这是获取 title标签文本
print('-' * 80) # 打印分割线
# zfill 是数字字符串进行补全0 在左边补全, 这样会好看点
print(str(parseIndex).zfill(3), u, t, ua) # 打印上面需要的参数进行查看
# 这个是获取 h1标签的 article-title 类 (class 属性) 的文本
article_title = _('h1.article-title').text()
stats_time = _('span.stats-time').text()
# span标签的 stats-vote 类 的 内 找 .number
stats_vote = _('span.stats-vote .number').text()
content = _('.content').text()
comment_block = [pq(_).text() for _ in _('.comment-block')] # 这个是列表生成式
self.parseIndex += 1
print(article_title)
print(stats_time, stats_vote)
print(content)
print('\n'.join(comment_block)) # 把列表转为字符串
# 使用 yield 推送字典到 数据处理
yield {
'article_title': article_title,
'stats_time': stats_time,
'stats_vote': stats_vote,
'content': content,
'comment_block': comment_block
}
item = {}
# item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get()
# item['name'] = response.xpath('//div[@id="name"]').get()
# item['description'] = response.xpath('//div[@id="description"]').get()
# return item
新建一个 start.py 用于运行
from scrapy.cmdline import execute
execute('scrapy crawl text'.split(' ')) # execute 传入必须列表 所以使用 split 就行分割字符串
基本就这些了, 先测试下
刷刷刷…
…
数据可以了,接入redis测试
开启redis服务
开启\reeNMS web端服务
文件自己找或者私聊
开启后效果
settings.py 修改
ITEM_PIPELINES = {
# 'qsbk.pipelines.QsbkPipeline': 300,
# 开启这个
'scrapy_redis.pipelines.RedisPipeline': 400,
}
# 开启这些
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
SCHEDULER_PERSIST = True
修改爬虫文件 text.py
# 增加导入 更改类的继承
from scrapy_redis.spiders import RedisSpider
# class TextSpider(CrawlSpider):
class TextSpider(RedisSpider):
# 注释掉
# start_urls = ['https://www.qiushibaike.com/text/page/1/']
新建 handle_redis.py 用于处理 redis
# CY3761 | 2021-11-17 11:31
import json
import redis
try:
# 加载redis
r = redis.Redis(host='127.0.0.1', port=6379)
k1 = 'TextSpider:start_urls'
# 如果不存在就进行追加第一页的地址
if not r.llen(k1):
r.lpush(k1, 'https://www.qiushibaike.com/text/page/1/')
print(r.llen(k1), r.lrange(k1, 0, -1))
k2 = 'text:items'
d2 = r.lrange(k2, 0, -1) # 列表
print(r.llen(k2), type(d2))
# 数据处理
for k, _ in enumerate(d2):
# print(type(_)) # <class 'bytes'>
# break
d2[k] = json.loads(_.decode('utf-8'))
# 数据显示
for k, _ in enumerate(d2):
k = str(k).zfill(3)
print('-' * 80)
print(k, _.get('article_title'))
print(_.get('stats_time'), _.get('stats_vote'))
print(_.get('content'))
print()
print('\n'.join(_.get('comment_block')))
k3 = 'text:dupefilter'
d3 = r.smembers(k3) # 集合
print()
print(r.scard(k3), type(d3))
for k, _ in enumerate(d3):
k = str(k).zfill(3)
print(k, _)
except (Exception, BaseException) as e:
print(e)
再测试吧
发现创建在py有点问题
等候 start_url
使用客户端添加
试了好久,发现问题了…
继承这里改一下
爬虫文件的继承
class TextSpider(RedisSpider, CrawlSpider):
由于请求过多, ip估计被禁了… 起码能实现… 应该还是有点问题的
暂时先这样…
2021-11-17 补
经过找资料等继承不需要2个的
from scrapy_redis.spiders import RedisCrawlSpider
# class TextSpider(CrawlSpider):
class TextSpider(RedisCrawlSpider):
redis 是重新清过的,可能redis一直在等 没发现会结束
git例子 github例子