《学习scrapy框架爬小说》的进一步完善
一、完善目标:
1、为方便使用,把小说拼音或英文名,小说输出中文名,第一章节url地址变量化,修改这些参数即可爬取不同的小说。
2、修改settings.py设置文件,配置为记录debug的log信息,以方便排错。
3、修改字符集编码,解决部分网页有emoji符号,导致无法把爬取的网页内容存入数据表的问题。(如:http://www.xbiquge.la/43/43474/19425972.html页面出现了
emoji符号)
二、实施过程
1、修改pipelines.py文件:
(python) [root@localhost xbiquge]# vi xbiquge/pipelines.py
self.url_firstchapter = "http://www.xbiquge.la/43/43474/19425971.html" #此处为小说的第一章节链接地址。
# -*- coding: utf-8 -*-
# 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
import os
import time
import pymysql
from twisted.enterprise import adbapi
from pymysql import cursors
class XbiqugePipeline(object):
#定义类初始化动作,包括连接数据库novels及建表
def __init__(self):
dbparams = {
'host':'127.0.0.1',
'port':3306,
'user':'root',
'password':'password',
'database':'novels',
'charset':'utf8mb4' #使用utf8mb4字符集可避免emoji表情符号无法存入数据表的错误,这是因为mysql的utf8只支持3个字节的存储,而一般字符是3个字节,但是emoji表情符号是4字节。(参见:《MySQL插入emoji表情错误的3种解决方案,Incorrect string value: '\xF0\x9F\x98\x84'》https://blog.csdn.net/dmw412724/article/details/81119325)
}
self.conn = pymysql.connect(**dbparams)
self.cursor = self.conn.cursor()
self._sql = None
self.name_novel = "heifen" #此处为小说的英文或拼音名,此名也是小说存储表文件名。
self.url_firstchapter = "http://www.xbiquge.la/43/43474/19425948.html" #此处为小说的第一章节链接地址。
self.name_txt = "老婆的头号黑粉" #此处为小说的中文名称,输出文件以此命名。
#爬虫开始
def open_spider(self,spider):
self.createtable() #爬虫开始时先初始化小说存储表
return
#建表
def createtable(self):
self.cursor.execute("drop table if exists "+ self.name_novel)
self.cursor.execute("create table " + self.name_novel + " (id int unsigned auto_increment not null primary key, url varchar(50) not null, preview_page varchar(50), next_page varchar(50), content TEXT not null) charset=utf8mb4")
return
def process_item(self, item, spider):
self.cursor.execute(self.sql, (item['url'], item['preview_page'], item['next_page'], item['content']))
self.conn.commit()
return item
@property
def sql(self):
if not self._sql:
self._sql = """
insert into """ + self.name_novel + """(id, url, preview_page, next_page, content) values(null, %s, %s, %s, %s)
"""
return self._sql
return self._sql
#从数据库取小说章节内容写入txt文件
def content2txt(self):
self.cursor.execute("select count(*) from " + self.name_novel)
record_num = self.cursor.fetchall()[0][0]
print(record_num)
counts=record_num
url_c = "\""+self.url_firstchapter+"\""
start_time=time.time() #获取提取小说内容程序运行的起始时间
f = open(self.name_txt+".txt", mode='w', encoding='utf-8') #写方式打开小说名称加txt组成的文件
for i in range(counts):
sql_c = "select content from " + self.name_novel + " where url=" + url_c #组合获取小说章节内容的sql命令。此处需要修改数据库文件名称
self.cursor.execute(sql_c)
record_content_c2a0=self.cursor.fetchall()[0][0] #获取小说章节内容
record_content=record_content_c2a0.replace(u'\xa0', u'') #消除特殊字符\xc2\xa0
f.write('\n')
f.write(record_content + '\n')
f.write('\n\n')
sql_n = "select next_page from " + self.name_novel + " where url=" + url_c #组合获取下一章链接的sql命令。此处需要修改数据库文件名称
self.cursor.execute(sql_n)
url_c = "\"" + self.cursor.fetchall()[0][0] + "\"" #下一章链接地址赋值给url_c,准备下一次循环。
f.close()
print(time.time()-start_time)
print(self.name_txt + ".txt" + " 文件已生成!")
return
#爬虫结束,调用content2txt方法,生成txt文件
def close_spider(self,spider):
self.content2txt()
return
2、spider文件:
(python) [root@localhost xbiquge]# vi xbiquge/spiders/heifen.py #爬虫文件可复制使用,不用再次使用scrapy genspider命令来产生。
# -*- coding: utf-8 -*-
import scrapy
from xbiquge.items import XbiqugeItem
class SancunSpider(scrapy.Spider): #此类是由scrapy genspider sancun www.xbiquge.la命令生成,抓取不同小说时,此类名可不用修改。
name = 'heifen' #不同的爬虫,此处需要设置不同的名字。
allowed_domains = ['www.xbiquge.la']
#start_urls = ['http://www.xbiquge.la/10/10489/']
def start_requests(self):
start_urls = ['http://www.xbiquge.la/43/43474/']
for url in start_urls:
yield scrapy.Request(url=url, callback=self.parse)
def parse(self, response):
dl = response.css('#list dl dd') #提取章节链接相关信息
for dd in dl:
self.url_c = "http://www.xbiquge.la" + dd.css('a::attr(href)').extract()[0] #组合形成小说的各章节链接
#print(self.url_c)
#yield scrapy.Request(self.url_c, callback=self.parse_c,dont_filter=True)
yield scrapy.Request(self.url_c, callback=self.parse_c) #以生成器模式(yield)调用parse_c方法获得各章节链接、上一页链接、下一页链接和章
节内容信息。
#print(self.url_c)
def parse_c(self, response):
item = XbiqugeItem()
item['url'] = response.url
item['preview_page'] = "http://www.xbiquge.la" + response.css('div .bottem1 a::attr(href)').extract()[1]
item['next_page'] = "http://www.xbiquge.la" + response.css('div .bottem1 a::attr(href)').extract()[3]
title = response.css('.con_top::text').extract()[4]
contents = response.css('#content::text').extract()
text=''
for content in contents:
text = text + content
#print(text)
item['content'] = title + "\n" + text.replace('\15', '\n') #各章节标题和内容组合成content数据,\15是^M的八进制表示,需要替换为换行符。
yield item #以生成器模式(yield)输出Item对象的内容给pipelines模块。
3、修改settings文件:
(python) [root@localhost xbiquge]# vi xbiquge/settings.py
...
ROBOTSTXT_OBEY = False
...
ITEM_PIPELINES = {
'xbiquge.pipelines.XbiqugePipeline': 300,
}
...
FEED_EXPORT_ENCODING = 'utf-8'
LOG_LEVEL = 'DEBUG'
LOG_FILE = './myspiders.log'
4、items.py文件:
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
import scrapy
class XbiqugeItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
url = scrapy.Field()
preview_page = scrapy.Field()
next_page = scrapy.Field()
content = scrapy.Field()
三、爬取不同小说的使用方法:
1、拷贝spider文件:cp heifen.py xueba.py
2、修改新spider文件中的爬虫名(name)和目录页url地址(start_urls):
(1)name = 'heifen' 修改为name = 'xueba';
(2)start_urls = ['http://www.xbiquge.la/43/43474/'] 修改为 start_urls = ['http://www.xbiquge.la/19/19639/']
3、修改pipelines.py文件中三个变量内容:self.name_novel、self.url_firstchapter、self.name_txt
4、运行爬虫程序(在/root/xbiquge目录下):scrapy runspider xbiquge/spiders/xueba.py
运行完成,即可在当前目录下(/root/xbiquge)看到生成的小说txt文件。爬虫运行debug信息可在/root/xbiquge/myspiders.log中查看。
《学习scrapy框架爬小说》的进一步完善的更多相关文章
- 学习scrapy框架爬小说
一.背景:近期学习python爬虫技术,感觉挺有趣.由于手动自制爬虫感觉效率低,了解到爬虫界有先进的工具可用,尝试学学scrapy爬虫框架的使用. 二.环境:centos7,python3.7,scr ...
- Python多线程爬图&Scrapy框架爬图
一.背景 对于日常Python爬虫由于效率问题,本次测试使用多线程和Scrapy框架来实现抓取斗图啦表情.由于IO操作不使用CPU,对于IO密集(磁盘IO/网络IO/人机交互IO)型适合用多线程,对于 ...
- 使用scrapy框架爬取自己的博文(2)
之前写了一篇用scrapy框架爬取自己博文的博客,后来发现对于中文的处理一直有问题- - 显示的时候 [u'python\u4e0b\u722c\u67d0\u4e2a\u7f51\u9875\u76 ...
- 爬虫入门(四)——Scrapy框架入门:使用Scrapy框架爬取全书网小说数据
为了入门scrapy框架,昨天写了一个爬取静态小说网站的小程序 下面我们尝试爬取全书网中网游动漫类小说的书籍信息. 一.准备阶段 明确一下爬虫页面分析的思路: 对于书籍列表页:我们需要知道打开单本书籍 ...
- scrapy框架爬取笔趣阁
笔趣阁是很好爬的网站了,这里简单爬取了全部小说链接和每本的全部章节链接,还想爬取章节内容在biquge.py里在加一个爬取循环,在pipelines.py添加保存函数即可 1 创建一个scrapy项目 ...
- Python使用Scrapy框架爬取数据存入CSV文件(Python爬虫实战4)
1. Scrapy框架 Scrapy是python下实现爬虫功能的框架,能够将数据解析.数据处理.数据存储合为一体功能的爬虫框架. 2. Scrapy安装 1. 安装依赖包 yum install g ...
- 使用scrapy框架爬取自己的博文(3)
既然如此,何不再抓一抓网页的文字内容呢? 谷歌浏览器有个审查元素的功能,就是按树的结构查看html的组织形式,如图: 这样已经比较明显了,博客的正文内容主要在div 的class = cnblogs_ ...
- 使用scrapy框架爬取自己的博文
scrapy框架是个比较简单易用基于python的爬虫框架,http://scrapy-chs.readthedocs.org/zh_CN/latest/ 这个是不错的中文文档 几个比较重要的部分: ...
- Python学习---爬虫学习[scrapy框架初识]
Scrapy Scrapy是一个框架,可以帮助我们进行创建项目,运行项目,可以帮我们下载,解析网页,同时支持cookies和自定义其他功能. Scrapy是一个为了爬取网站数据,提取结构性数据而编写的 ...
随机推荐
- 一文带你深入了解 Lambda 表达式和方法引用
前言 尽管目前很多公司已经使用 Java8 作为项目开发语言,但是仍然有一部分开发者只是将其设置到 pom 文件中,并未真正开始使用.而项目中如果有8新特性的写法,例如λ表达式.也只是 Idea Al ...
- schedule定时任务出现问题 (大坑已填)!!
因为python每次运行完,并不清除内存,nowtime一直不变,这导致了一个致命问题,使我的脚本一直运行失败,具体如下: 我设置的是每隔30分钟登陆一次,代码如下 if __name__ == &q ...
- 设计模式(Java语言)- 建造者模式
前言 在日常的生活中,我们可以经常看到建造者模式的影子.比如,建造房子,那么房子就是一个产品,房子由门,窗,墙,地板等部门组成.然后包工头在建造房子的时候就根据设计好的图纸来建造,但是包工头并不是亲自 ...
- AntDesignPro的权限控制和动态路由
最近看了AntDesignPro关于权限控制的官方文档以及自己框架里权限控制的实现,总结一下. 先贴一下官网上关于权限控制的图有利于理解 步骤如下: 判断是否有 AccessToken 如果没有则跳转 ...
- Neo4j填坑记录-Neo4jClient建立节点、建立关系相关
最近一个项目需要用到知识图谱,选用了neo4j图数据库,在这过程中遇到几个坑,记录一下 1.无法登录,疯狂提示“WebSocket connection failure. Due to securit ...
- Spring Cloud 系列之 Bus 消息总线
什么是消息总线 消息代理中间件构建一个共用的消息主题让所有微服务实例订阅,当该消息主题产生消息时会被所有微服务实例监听和消费. 消息代理又是什么?消息代理是一个消息验证.传输.路由的架构模式,主要用来 ...
- 类型信息(反射,RTTI)
类型信息 1.java如何在运行时识别对象和类的信息 "传统的"RTTI run-time type identification ,假设我们在编译时已经知道了所有类型,在编译的时 ...
- 如何在一台计算机上安装多个 JDK 版本
前言 对于使用 Java 语言开发的朋友可能会遇到这种情况,有时想学习和探索 Java 的最新版本提供的一些新特性,比如 Java 11,但你无法将其安装在自己的计算机上,因为你的团队正在使用比这个旧 ...
- leetcode 第184场周赛第一题(数组中的字符串匹配)
一.函数的运用 1,strstr(a,b); 判断b是否为a的子串,如果是,返回从b的开头开始到a的结尾 如“abcdefgh” “de” 返回“defgh”: 如果不是子串,返回NULL: 2,me ...
- zz 通过INFORMATION_SCHEMA.INNODB_TRX、INNODB_LOCKS、INNODB_LOCK_WAITS 三个表获取事务与锁的信息
zz from http://imysql.com/2015/03/25/mysql-faq-how-to-fetch-latest-trxid.shtml #先查询 INNODB_TRX 表,看看都 ...