初探scrapy(用scrapy爬取一部小说)

  • A+
所属分类:Python

初探scrapy(用scrapy爬取一部小说) - 进入python的世界-killeri - CSDN博客

初探scrapy(用scrapy爬取一部小说)

讲起来我跟笔趣看真有不解之缘,之前刚学习python时就是用笔趣看作为试验网站,现在刚接触scrapy框架也是用它来练手。
今天说的是用scrapy爬取一步小说
假设你已经安装了scrapy!
第一步:创建一个scrapy’项目
在命令行输入

scrapy startproject biqukanproject
这样就创建了一个scrapy项目
第二步:在项目内创建一个爬虫
在项目命令行处输入
scrapy genspider biqukanspider biqukan.com
解释一下这行命令的参数:
一、biqukanspider 这个参数是创建的这个爬虫的名称(后面爬虫的调用就是用这个名称)
二、biqukan.com 这是该爬虫允许爬取的域名(也就是说爬虫只能在这个域名范围内进行爬取)
经过以上的两步我们已经创建了一个爬虫项目,就可以编写爬虫了
接下来编写爬虫:
在刚创建的spider里面编写爬虫
由于我们要抓取的是一个完整的小说,那么就要先抓取每个章节的链接,然后在通过链接抓取小说的内容
抓取的链接的页面:
5d7218f2700e3871c4000000_html_.png
在这个页面抓取了链接以后,利用这个链接抓取详情页的内容:
5d7218f2700e3871c4000001_html_.png
那么明显我们就需要两个方法,分别提取两个链接和内容,并将两个方法关系起来就可以了
接下来就直接贴上这个代码,都有注释,很简单可以看懂:
文件 biqukanspider.py 的代码

-- coding: utf-8 --

import scrapy
from scrapy.selector import Selector
from biqukanproject.items import BiqukanprojectItem
class BiqukanspiderSpider(scrapy.Spider):
    name = 'biqukanspider' # 爬虫的名称
    allowed_domains = ['biqukan.com'] # 允许的域名
    start_urls = ['http://biqukan.com/0_790/']
    # 开始爬取的链接
    def parse(self, response):
    # 链接爬取的方法
        selector = Selector(response)
        # 创建一个选择器的实例
        listmain = selector.xpath('.//div[@class="listmain"]/dl/dd')[60:64]
        for dd in listmain:
            title_novel = selector.xpath('.//h2/text()').extract_first()
            item = BiqukanprojectItem(title_novel=title_novel)
            partial_url = dd.xpath('.//a/@href').extract_first()
            url = response.urljoin(partial_url)
            title_chapter = dd.xpath('.//a/text()').extract_first()
            item['url'] = url
            item['title_chapter'] =title_chapter
            request = scrapy.Request(url=url,callback=self.parse_body)
            # 从这里可以看出,scrapy.Request返回值是它回调函数的返回值
            # Request中有一个参数是meta
            # 作用是将一个信息(任意的类型)传递给callback回调函数
            # 当然传递使用字典的形式进行的,
            # meta={'key':item}  (下面的request.meta【‘item’】可以这么写)
            # 这里为了将详情页的内容和主页的内容一起存储,用了meta方法对,主页的内容
            # 进行了一个暂存,在后面进行统一的提交
            request.meta['item'] = item # 将item暂存一下
            yield request
    def parse_body(self,response):
    # 爬取详情页的方法
        item = response.meta['item']
        # 这是在回调函数中调用刚传进来的信息
        # 当然用的是字典的形式调用信息的呀
        # 这是回调函数中有一个response的meta属性可以调用传过来的信息
        content_list = response.xpath('.//div[@id="content"]/text()').extract()
        content = '\n\n'.join(content_list)
        # 提取详情页的内容
        item['content'] = content
        yield item
        # yield是将这个函数包装成一个迭代器,每次调用都返回这个item

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

以上基本上就是程序的主体,接下来还有其它几个文件
setting.py
用于爬虫工程的相关参数的设置
ITEM_PIPELINES = {
   'biqukanproject.pipelines.BiqukanprojectPipeline': 300,
}
这个参数用于激活pipeline

USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36'

用于设置请求头

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

settings.py里面还有一些别的参数,自己看看,需要激活的就只有这两个,在这个爬虫里面
items.py
定义需要抓取的数据的一个文件
import scrapy
class BiqukanprojectItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    url = scrapy.Field()
    title_novel = scrapy.Field()
    title_chapter = scrapy.Field()
    content = scrapy.Field()

上面定义了四个抓取的数据

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

pipeline.py
用于存放处理数据功能的文件,该文件中定义了一些方法用于处理item中的数据
class BiqukanprojectPipeline(object):
    def init(self):
        self.file = open('novel.json',"wb")
    def process_item(self, item, spider):
        self.file.write(bytes(str(item),encoding='utf-8'))
        return item

这里是将item数据写入一个novel.json文件中

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

以上就是全部内容,我会更新哦,关注一个吧!

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin