Python爬虫:爬取小说并存储到数据库

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介:

爬取小说网站的小说,并保存到数据库


第一步:先获取小说内容

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
#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
import  urllib2,re
 
domain  =  'http://www.quanshu.net'
headers  =  {
     "User-Agent" "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"
}
 
def  getTypeList(pn = 1 ):  #获取分类列表的函数
     req  =  urllib2.Request( 'http://www.quanshu.net/map/%s.html'  %  pn)  #实例将要请求的对象
     req.headers  =  headers   #替换所有头信息
     #req.add_header() #添加单个头信息
     res  =  urllib2.urlopen(req)    #开始请求
     html  =  res.read().decode( 'gbk' )   #decode解码,解码成Unicode
     reg  =  r '<a href="(/book/.*?)" target="_blank">(.*?)</a>'
     reg  =  re. compile (reg)  #增加匹配效率  正则匹配返回的类型为List
 
     return  re.findall(reg,html)
 
def  getNovelList(url):   #获取章节列表函数
     req  =  urllib2.Request(domain  +  url)
     req.headers  =  headers
     res  =  urllib2.urlopen(req)
     html  =  res.read().decode( 'gbk' )
     reg  =  r '<li><a href="(.*?)" title=".*?">(.*?)</a></li>'
     reg  =  re. compile (reg)
     return  re.findall(reg,html)
 
def  getNovelContent(url):   #获取章节内容
     req  =  urllib2.Request(domain  +  url)
     req.headers  =  headers
     res  =  urllib2.urlopen(req)
     html  =  res.read().decode( 'gbk' )
     reg  =  r 'style5\(\);</script>(.*?)<script type="text/javascript">style6\(\)'
     return  re.findall(reg,html)[ 0 ]
 
 
if  __name__  = =  '__main__' :
     for  type  in  range ( 1 , 10 ):
         for  url,title  in  getTypeList( type ):
             for  zurl,ztitle  in  getNovelList(url):
                 print  u '正则爬取----%s'  % ztitle
                 content  =  getNovelContent(url.replace( 'index.html' ,zurl))
                 print  content
             break
         break


执行后结果如下:

wKiom1kpIdThRNdaAAIyGKHHJXo728.png




第二步:存储到数据库

1、设计数据库

1.1 新建库:novel

wKiom1kpOr7yfa9aAABoSmd-OnA036.png


1.2 设计表:novel

wKioL1kpOvXi6UDzAABUheeLxB0623.png


1.3 设计表:chapter

wKiom1kpO4CgKxdUAAB6tbFOxwU677.png


并设置外键

wKioL1kpO4CANrBSAABInMXtb-E068.png




2、编写脚本

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
55
56
57
58
59
60
61
62
63
64
65
#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
import  urllib2,re
import  MySQLdb
 
class  Sql( object ):
     conn  =  MySQLdb.connect(host = '192.168.19.213' ,port = 3306 ,user = 'root' ,passwd = 'Admin123' ,db = 'novel' ,charset = 'utf8' )
     def  addnovels( self ,sort,novelname):
         cur  =  self .conn.cursor()
         cur.execute( "insert into novel(sort,novelname) values(%s , '%s')"  % (sort,novelname))
         lastrowid  =  cur.lastrowid
         cur.close()
         self .conn.commit()
         return  lastrowid
     def  addchapters( self ,novelid,chaptername,content):
         cur  =  self .conn.cursor()
         cur.execute( "insert into chapter(novelid,chaptername,content) values(%s , '%s' ,'%s')"  % (novelid,chaptername,content))
         cur.close()
         self .conn.commit()
 
 
domain  =  'http://www.quanshu.net'
headers  =  {
     "User-Agent" "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"
}
 
def  getTypeList(pn = 1 ):  #获取分类列表的函数
     req  =  urllib2.Request( 'http://www.quanshu.net/map/%s.html'  %  pn)  #实例将要请求的对象
     req.headers  =  headers   #替换所有头信息
     #req.add_header() #添加单个头信息
     res  =  urllib2.urlopen(req)    #开始请求
     html  =  res.read().decode( 'gbk' )   #decode解码,解码成Unicode
     reg  =  r '<a href="(/book/.*?)" target="_blank">(.*?)</a>'
     reg  =  re. compile (reg)  #增加匹配效率  正则匹配返回的类型为List
 
     return  re.findall(reg,html)
 
def  getNovelList(url):   #获取章节列表函数
     req  =  urllib2.Request(domain  +  url)
     req.headers  =  headers
     res  =  urllib2.urlopen(req)
     html  =  res.read().decode( 'gbk' )
     reg  =  r '<li><a href="(.*?)" title=".*?">(.*?)</a></li>'
     reg  =  re. compile (reg)
     return  re.findall(reg,html)
 
def  getNovelContent(url):   #获取章节内容
     req  =  urllib2.Request(domain  +  url)
     req.headers  =  headers
     res  =  urllib2.urlopen(req)
     html  =  res.read().decode( 'gbk' )
     reg  =  r 'style5\(\);</script>(.*?)<script type="text/javascript">style6\(\)'
     return  re.findall(reg,html)[ 0 ]
 
mysql  =  Sql()
if  __name__  = =  '__main__' :
     for  sort  in  range ( 1 , 10 ):
         for  url,title  in  getTypeList(sort):
             lastrowid  =  mysql.addnovels(sort, title)
             for  zurl,ztitle  in  getNovelList(url):
                 print  u '正则爬取----%s'  % ztitle
                 content  =  getNovelContent(url.replace( 'index.html' ,zurl))
                 print  u '正在存储----%s'  % ztitle
                 mysql.addchapters(lastrowid,ztitle,content)


3、执行脚本

wKioL1kpO_SwfYOdAAHAvlowP2k275.png


4、查看数据库

wKioL1kpRJ7hsGI_AABKvJGXbtY583.png


wKioL1kpRKvyQVNUAAEwW-UKPY8568.png

可以看到已经存储成功了





报错:

_mysql_exceptions.OperationalError: (1364, "Field 'novelid' doesn't have a default value")


解决:执行sql语句

SELECT @@GLOBAL.sql_mode;

SET @@GLOBAL.sql_mode="NO_ENGINE_SUBSTITUTION";


wKioL1kpPCXjTHm5AABPJKISpZs573.png



报错参考:http://blog.sina.com.cn/s/blog_6d2b3e4901011j9w.html






      本文转自M四月天 51CTO博客,原文链接:http://blog.51cto.com/msiyuetian/1931102,如需转载请自行联系原作者






相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
25天前
|
数据采集 Web App开发 数据安全/隐私保护
实战:Python爬虫如何模拟登录与维持会话状态
实战:Python爬虫如何模拟登录与维持会话状态
|
2月前
|
数据采集 Web App开发 自然语言处理
新闻热点一目了然:Python爬虫数据可视化
新闻热点一目了然:Python爬虫数据可视化
|
3月前
|
数据采集 数据挖掘 测试技术
Go与Python爬虫实战对比:从开发效率到性能瓶颈的深度解析
本文对比了Python与Go在爬虫开发中的特点。Python凭借Scrapy等框架在开发效率和易用性上占优,适合快速开发与中小型项目;而Go凭借高并发和高性能优势,适用于大规模、长期运行的爬虫服务。文章通过代码示例和性能测试,分析了两者在并发能力、错误处理、部署维护等方面的差异,并探讨了未来融合发展的趋势。
285 0
|
1月前
|
数据采集 监控 数据库
Python异步编程实战:爬虫案例
🌟 蒋星熠Jaxonic,代码为舟的星际旅人。从回调地狱到async/await协程天堂,亲历Python异步编程演进。分享高性能爬虫、数据库异步操作、限流监控等实战经验,助你驾驭并发,在二进制星河中谱写极客诗篇。
Python异步编程实战:爬虫案例
|
2月前
|
数据采集 存储 XML
Python爬虫技术:从基础到实战的完整教程
最后强调: 父母法律法规限制下进行网络抓取活动; 不得侵犯他人版权隐私利益; 同时也要注意个人安全防止泄露敏感信息.
638 19
|
1月前
|
数据采集 存储 JSON
Python爬虫常见陷阱:Ajax动态生成内容的URL去重与数据拼接
Python爬虫常见陷阱:Ajax动态生成内容的URL去重与数据拼接
|
1月前
|
数据采集 存储 JavaScript
解析Python爬虫中的Cookies和Session管理
Cookies与Session是Python爬虫中实现状态保持的核心。Cookies由服务器发送、客户端存储,用于标识用户;Session则通过唯一ID在服务端记录会话信息。二者协同实现登录模拟与数据持久化。
|
2月前
|
数据采集 存储 Web App开发
处理Cookie和Session:让Python爬虫保持连贯的"身份"
处理Cookie和Session:让Python爬虫保持连贯的"身份"
|
2月前
|
数据采集 Web App开发 前端开发
处理动态Token:Python爬虫应对AJAX授权请求的策略
处理动态Token:Python爬虫应对AJAX授权请求的策略
|
2月前
|
数据采集 网络协议 API
协程+连接池:高并发Python爬虫的底层优化逻辑
协程+连接池:高并发Python爬虫的底层优化逻辑

推荐镜像

更多