赞
踩
目录
目标网址:http://www.daomubiji.com/
1.Python中os.mkdir()与os.makedirs()的区别及用法
- # 调度器 使用scrapy-redis
- SCHEDULER = "scrapy redis.scheduler.Scheduler"
- # 去重的 使用scrapy-redis
- DUPEFILTER_CLASS = "scrapy_redis.dupeŨ lter.RFPDupeFilter"
- # 断点续爬 请求持久化
- SCHEDULER_PERSIST = True
- ITEM_PIPELINES = {
- 'dmbj.pipelines.DmbjPipeline': 300,
- # 数据保存到redis
- 'scrapy_redis.pipelines.RedisPipeline': 400,
- }
- import scrapy
- from dmbj.items import DmbjItem
- import re, os
- from copy import deepcopy
-
- # redis要导入的内容
- from scrapy_redis.spiders import RedisSpider
-
- class SpiderSpider(RedisSpider):
-
- name = 'spider'
- # allowed_domains = ['daomubiji.com']
- # start_urls = ['http://daomubiji.com/']
-
- # redis要写成这个
- redis_key = 'dmbj'
-
- def parse(self, response):
- """一级爬取"""
- text = response.text
-
- html = response.xpath('//ul[@class="sub-menu"]//a')
-
- for i in html:
- item = DmbjItem()
- # 书名
- item['book_name'] = i.xpath('./text()').get()
- # 连接
- book_link = i.xpath('./@href').get()
-
- # 书名记得替换特殊字符,预防引发爬取时变成转义字符
- book_path = re.sub(r'[\\\/\:\*\?\"\<\>\|]', '_', item['book_name'])
- # 书本存放路径
- dirpath = f'./noval/{book_path}'
- # 每本书一个文件见存放
- if not os.path.exists(dirpath):
- os.makedirs(dirpath)
-
- # 发送请求到下一级爬取 记得用深拷贝
- yield scrapy.Request(url=book_link, callback=self.second_parse, meta={'item': deepcopy(item)})
-
- def second_parse(self, response):
- """二级爬取"""
-
- # 接受上一个参数的传参
- item = response.meta.get('item')
- article_list = response.xpath('//div[@class="excerpts"]//article')
-
- for i in article_list:
- # 章节名字
- item['chapter_title'] = i.xpath('./a/text()').get()
-
- # 章节链接
- content_link = i.xpath('./a/@href').get()
-
- yield scrapy.Request(url=content_link, callback=self.third_parse, meta={'item': deepcopy(item)})
-
-
- def third_parse(self,response):
- """三级爬取"""
- item = response.meta.get('item')
-
- content = response.xpath('//article[@class="article-content"]/p/text()').getall()
- # 每个段落用换行代替
- item['content'] = '\n'.join(content)
-
- yield item
设计知识点:
首先说os.mkdir(path),他的功能是一级一级的创建目录,前提是前面的目录已存在,如果不存在会报异常。
- import os
-
- os.mkdir('d:\hello') # 正常
- os.mkdir('d:\hello\hi') # 正常
-
- # 如果d:\hello目录不存在
- # 则os.mkdir('d:\hello\hi')执行失败
然后是os.makedirs(path),可以一次创建多级目录,中间目录不存在也能正常的创建。
- import os
-
- os.makedirs('d:\hello') # 正常
- os.makedirs('d:\hello\hi') # 正常
-
- # 如果d:\hello目录不存在
- # 则os.makedirs('d:\hello\hi') # 仍然正常
参考这篇博客:copy与deepcopy的区别
上一级爬虫发送
yield scrapy.Request(url=content_link, callback=self.third_parse, meta={'item': deepcopy(item)})
下级爬虫接受
item = response.meta.get('item')
每个段落用换行合并
- # 每个段落用换行代替
- item['content'] = '\n'.join(content)
- # 书名记得替换特殊字符,预防引发爬取时变成转义字符
- book_path = re.sub(r'[\\\/\:\*\?\"\<\>\|]', '_', item['book_name'])
- import scrapy
-
-
- class DmbjItem(scrapy.Item):
- # define the fields for your item here like:
- # name = scrapy.Field()
- # 书名
- book_name = scrapy.Field()
- # 章节名
- chapter_title = scrapy.Field()
- # 章节内容
- content = scrapy.Field()
- import re
-
- class DmbjPipeline:
-
- def open_spider(self,spider):
- pass
-
-
- def process_item(self, item, spider):
- # 替换字符
- self.book_name = re.sub(r'[\\\/\:\*\?\"\<\>\|]', '_', item['book_name'])
- self.chapter_title = re.sub(r'[\\\/\:\*\?\"\<\>\|]', '_', item['chapter_title'])
-
- # 创建文件
- self.f = open(f'./noval/{self.book_name}/{self.chapter_title}.txt','w',encoding='utf-8')
- # 写入
- self.f.write(item["content"])
-
- return item
-
-
- def close_spider(self,spider):
- self.f.close()
- # 调度器 使用scrapy_redis
- SCHEDULER = "scrapy_redis.scheduler.Scheduler"
- # 去重 使用scrapy_redis
- DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
- # 断点续爬 请求持久化
- SCHEDULER_PERSIST = True
-
-
- ITEM_PIPELINES = {
- 'dmbj.pipelines.DmbjPipeline': 300,
- # 数据保存到redis
- 'scrapy_redis.pipelines.RedisPipeline': 400,
- }
需要打开redis.py,而且创建redis列表,和起始地址
然后开启多个终端模拟多台电脑运行即可
python3.10之后要做出的修改,在spiders.py的源代码里面
from collections import Iterable 为 from collections.abc import Iterable
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。