Python | 实战Scapy,爬取起点网全部小说!

640?wx_fmt=jpeg

作者:totcw

来源:http://blog.csdn.net/totcw/article/details/65444660

目录:

  1. 概述 

  2. 创建项目 

  3. item的编写 

  4. pipelines的编写 

  5. setting的编写

  6. spider的编写

  7. 总结 



处于兴趣爱好,最近正好在写一个爬虫类的项目,也算是重新拾了一把Scapy。今天这篇文章就先给大家带个路,接下来我会等项目MVP出来后和大家分享。

代码部分我都做了注释,如果有不清楚的欢迎留言。希望每篇Python文章都能带给大家一些帮助。

1. 概述 

本篇的目的是用scrapy来爬取起点小说网的完本小说,使用的环境ubuntu,至于scrapy的安装就自行百度了. 

2. 创建项目 

scrapy startproject name 通过终端进入到你创建项目的目录下输入上面的命令就可以完成项目的创建.name是项目名字. 


3. Item的编写 

我这里定义的item中的title用来存书名,desc用来存书的内容.

import scrapy

class TutorialItem(scrapy.Item):
    # name = scrapy.Field()
    title = scrapy.Field()
    desc = scrapy.Field()
    pass


4. pipelines的编写 

在pipelines可以编写存储数据的形式,我这里就是使用txt形式的文件来存储每一本书

import json
import codecs

# 以txt的形式存储,其实也就是一个存储方式
class TutorialPipeline(object):

    def process_item(self, item, spider):
       # 根据书名来创建文件
       item.get('title') # 就可以获取到书名
        self.file = codecs.open(item.get('title')+'.txt', 'w', encoding='utf-8')
        self.file.write(item.get("desc")+ "\n")
        return item

    def spider_closed(self, spider):
        self.file.close()

5. setting的编写

只要将下面代码中的tutorial替换成自己项目的名字就可以

BOT_NAME = 'tutorial'
#USER_AGENT
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.54 Safari/536.5'
# start MySQL database configure setting

# end of MySQL database configure setting

SPIDER_MODULES = ['tutorial.spiders']
NEWSPIDER_MODULE = 'tutorial.spiders'

# Crawl responsibly by identifying yourself (and your website) on the user-agent
# USER_AGENT = 'tutorial (+http://www.yourdomain.com)'
ITEM_PIPELINES = {
    'tutorial.pipelines.TutorialPipeline': 300,
}


6.spider的编写

import scrapy
from scrapy.spider import BaseSpider
from scrapy.selector import HtmlXPathSelector
from tutorial.items import TutorialItem
from scrapy.http import Request


class DmozSpider(scrapy.Spider):
    name = "dmoz"
    allowed_domains = ["dmoz.org"]
    # 我这里是下载起点体育类的完本小说,所以通过for来创建每一个页面的url,因为每一个只是page不同而已,而page是根据全部的本数/页数而来
    start_urls = [
        "http://fin.qidian.com/?size=-1&sign=-1&tag=-1&chanId=8&subCateId=-1&orderId=&update=-1&page="+str(page)+"&month=-1&style=1&vip=-1" for page in range(1,292/20)
    ]

    def parse(self, response):
        hxs = HtmlXPathSelector(response)
        # 获取每一个书的url
        book =hxs.select('//div[@class="book-mid-info"]/h4/a//@href').extract()
        for bookurl in book:
          # 根据获取到的书本url跳转到每本书的页面
         # self.parseBook 是回调函数,作为请求后的处理逻辑
          yield Request("http:"+bookurl, self.parseBook, dont_filter=True)


    def parseBook(self,response):
        hxs = HtmlXPathSelector(response)
        # 获取免费阅读的url
       # 这里用的是css选择器了,其实xpath更方便些我感觉
        charterurl = hxs.select('//div[@class="book-info "]//a[@class="red-btn J-getJumpUrl "]/@href').extract()
        # 每一本书都创建一个item
        item = TutorialItem()
        for url in charterurl:
            # 通过免费阅读的url进入书的第一章
            yield Request("http:"+url,meta={'item': item},callback=self.parseCharter, dont_filter=True)


    def parseCharter(self ,response):
        hxs = HtmlXPathSelector(response)
        # 获取书名
        names = hxs.select('//div[@class="info fl"]/a[1]/text()').extract()
        # 获取上面传递过来的item
        item = response.meta['item']
        for name in names:
            # 将书名存入到item的title字段中
            names = item.get('title')
            if None==names:
                item['title'] = name
        # 获取章节名
        biaoti = hxs.select('//h3[@class="j_chapterName"]/text()').extract()
        content = ''
        for biaot in biaoti:
            content=content+biaot+"\n"
        # 获取每一章的内容
        s = hxs.select('//div[@class="read-content j_readContent"]//p/text()').extract()
        for srt in s:
            # 将章节和内容拼接起来存入到item的desc中
            content = content + srt
        desc = item.get('desc')
        if None==desc:
            item['desc'] =content
        else:
           item['desc']=desc+content
        if content=='':
            yield item

        # 获取下一章的内容
        chapters = hxs.select('//div[@class="chapter-control dib-wrap"]/a[@id="j_chapterNext"]//@href').extract()
        for chapter in chapters:
            # print "https:" + chapter
          yield Request("http:" + chapter, meta={'item': item},callback=self.parseCharter, dont_filter=True)

7.总结 

通过上面的代码虽然可以获取所有书的内容,但是起点是有vip限制的,也就是说必须用起点的vip帐号登录才能查看完本的小说,因此这有点遗憾,我没有起点小说网的会员.



推荐阅读:

万字谏言,给那些想学Python的人,建议收藏后细看!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值