python爬虫:爬取豆瓣阅读出版社数据

1.写在前面

作为一名数据分析狮,掌握基础的爬虫技能必不可少。若需要查看爬取豆瓣阅读出版社请查看文章最后,前面部分为基础介绍。

2.网络爬虫

爬虫类型很多,常用的有通用网络爬虫(爬取网站所有内容)和聚焦网络爬虫(针对某一特定需求)

3爬虫原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ayGTorSC-1584147798547)(attachment:image.png)]

4. 正则表达式(重要)

4.1 什么是正则表达式:

是一种进行数据筛选的表达式。如果我们想提取需要的数据,可以通过表达式进行提取。
正则表达式的模块:re模块

5. 原子:

正则表达式的最基本的组成单位。每个正则表达式中至少包含一个原子。

常见的原子类型:

普通字符作为原子;非打印字符;通用字符;原子表

5.1 打印字符作为原子。普通中英文都属于打印字符。

#调用正则模块
import re
#定义规则
pat1='常小宇'
string1='中国传媒大学常小宇'
#使用re模块的search函数找到指定的内容,第一个参数是规则,第二个参数是总的字符串
ret1=re.search(pat1,string1)
print(ret1)

#调用正则模块
import re
#定义规则
pat2='cxy'
string2='zhongchuan'
#使用re模块的search函数找到指定的内容,第一个参数是规则,第二个参数是总的字符串
ret2=re.search(pat2,string2)
print(ret2)
#此时总字符串里不满足规则,所有没有输出
None

5.2 非打印字符作为原子。非打印字符指不会打印显示的字符,例如:

\n:换行符号; \t :tab符进行缩进对齐

import re
pat3='\n'
#使用三引号才能在字符串里出现换行
string3='''zhongchuan
cxy'''
ret3=re.search(pat3,string3)
print(ret3)

5.3 通用字符作为原子。

例如:

\w:任意的一个字母、数字或下划线 (即非特殊字符);\d: 任意一个十进制数 ;\s: 空白字符 ;

\W(大写):与 \w 相反的字符,即除了字母、数字或下划线以外的任意一个字符 ; \D:除了十进制数以外的任意一个字符; \S:除了空白字符以外的任意一个字符

import re 
pat4='\w\dcxy\w' 
string4='hgsajhakjhsku'
ret4=re.search(pat4,string4)
print(ret4)
None
import re 
pat5='\w\dcxy\w' 
string5='hgsajhak1cxyjhsku'
ret5=re.search(pat5,string5)
print(ret5)

import re  
pat6='\w\dcxy\w' 
string6='hgsajhak123cxyjhsku'
ret6=re.search(pat6,string6)
print(ret6)

3.3 原子表:定义一组平等的原子。

原子用中括号 [ ] 括起来,中括号内是原子

import re 
pat7='ab[cxy]n'#该规则是前2位是abn第三位是c,x,y中的任意一个,第4位是n。这里的[cxy]是三个原子
string7='hgsajhakabynjhsku'#abyn符合规则
ret7=re.search(pat7,string7)
print(ret7)

import re 
pat7='ab[cxy]n'#该规则是前2位是abn第三位是c,x,y中的任意一个,第4位是n。这里的[cxy]是三个原子
string7='hgsajhakabcynjhsku'#abcyn中多了一个,不符合规则所以提取不出来东西
ret7=re.search(pat7,string7)
print(ret7)
None
import re 
pat8='学生[甲乙丙]18级'#该规则是前2位是学生,第三位是甲、乙、丙中的任意一个,第4-6位是18级
string8='北京市中国传媒大学学生甲18级'
ret8=re.search(pat8,string8)
print(ret8)

6. 元字符:

正则表达式中具有一些特殊含义的字符,比如重复N次前面的字符等。常见元字符有:

字符 . :可以匹配除了换行符以外的任意一个字符

字符^ :匹配待搜索字符串的开始位置

字符 $ :匹配待搜索字符串的结束位置

字符 * :匹配出现1次、2次或者多次的字符。例如:s*可以匹配s,ss,sss

字符 ? :匹配出现1次或者2次。例如:s?可以匹配s,ss,但不能匹配sss

字符 + :匹配出现2次或者多次。例如:s+可以匹配ss,ssss,但不能匹配s

字符 a|b :模式选择符,表或者的关系。例如:a|b表示a或者b,但是不能同时匹配出a和b

字符 ( ) :模式端源,提取特定内容

字符 a{n }:匹配字母(用a代指)出现了n次。例如:t{3}可以匹配ttt;x{6}可以匹配xxxxxx

字符 a{n,} :匹配字母(用a代指)至少出现了n次。例如:t{3}可以匹配ttt、tttt或者ttttttt等连续t的个数大于3的字符串

字符 a{n,m}:匹配字母(用a代指)出现的次数在n至m之间。例如:t{1,3}可以匹配t、tt或者ttt

6.1 字符 .

可以匹配除了换行符以外的任意一个字符。

import re
pat9='.python...'#该规则提取10个字符,第1个字符为除了换行符以外的任意一个字符,2-7为python,8-10为除了换行符以外的任意一个字符
string9='hgsaipythoncxyhsku'
ret9=re.search(pat9,string9)
print(ret9)

import re
pat10='.常小宇...'#该规则提取8个字符,第1个字符为除了换行符以外的任意一个字符,2-4为常小宇,5-8为除了换行符以外的任意一个字符
string10='中国传媒大学常小宇123456'
ret10=re.search(pat10,string10)
print(ret10)

6.2 字符 a|b :模式选择符,表或者的关系。例如:a|b表示a或者b,但是不能同时匹配出a和b

import re
pat11='中传|CUC'#该规则提取“中传”或者“CUC”
string11='中传数据科学与智能媒体学院'
ret11=re.search(pat11,string11)
print(ret11)

import re
pat12='中传|CUC'#该规则提取“中传”或者“CUC”
string12='CUC中传数据科学与智能媒体学院CUC'
#字符 | 是或者的关系,只能提取二者之一。CUC和中传二者同时出现时,只匹配出现的第一个CUC。若需要把后面的也输出,需要将search()函数换为全局匹配函数
ret12=re.search(pat12,string12)
print(ret12)

7. 模式修正符:

可以在不改变正则表达式的情况下,通过模式修正符改变正则表达式的含义,从而实现对匹配结果的调整等功能。

7.1 常见修正符

I:不区分大小写;
M:多行匹配;
L:本地化识别匹配;
U:根据Unicode字符解析;
S:让点也匹配换行符

7.2 模式修正符使用:

re.模式修正符

import re
pat13='python'
string13='CvwxjjafjPythonwxC'
ret13=re.search(pat13,bstring13)
print(ret13)#此时提取不出来,因为规则是小写python,string13中是大写Python
None

7.2 模式修正符使用:re.模式修正符

import re
pat13='python'
string13='CvwxjjafjPythonwxC'
ret13=re.search(pat13,string13,re.I)#加入了不区分大小写的模式修正符re.I
print(ret13)

8. 贪婪模式:尽可能多的匹配

import re
pat14='p.*y'
#该规则是贪婪模式,会匹配多次符合规则的字符:开始字符是p,结束字符是y,中间.*表示匹配出现1、2次或多次的除了换行符以外的任意多个字符。
string14='asdfghjkpythonvbzxnmckfhegorjwny'
ret14=re.search(pat14,string14)
print(ret14)

import re
pat15='中.*传'#该规则是贪婪模式,会匹配多次符合规则的字符
string15='数据科学与智能媒体学院中应用数学专业传播学统计中间传来了呼唤中传CUC大学'
ret15=re.search(pat15,string15)
print(ret15)

8.1 懒惰模式:尽可能少的匹配

import re
pat16='中.?传'#该规则是懒惰模式:开始是中,结束是传,中间.?表示匹配出现1次的除了换行符以外的一个字符
string16='数据科学与智能媒体学院中露露传数学专业传播学统计中间传来了呼唤中传CUC大学'
ret16=re.search(pat16,string16)
print(ret16)

import re
pat17='p.?y'#该规则是懒惰模式
string17='asdfghjkpsythonvbzxnmckfhegorjwny' 
ret17=re.search(pat17,string17) 
print(ret17)

9. 正则表达式函数:

有re.search()和re.match()函数、全局匹配函数、re.sub()函数

9.1 re.search()函数:符合规则的字符可以出现在任意位置,都可以匹配。但只输出第1次的匹配结果

import re
pat16='中.?传'#该规则是懒惰模式:开始是中,结束是传,中间.?表示匹配出现1次的除了换行符以外的一个字符
string16='数据科学与智能媒体学院中露露传数学专业传播学统计中间传来了呼唤中传CUC大学中房传'
ret16=re.search(pat16,string16)
print(ret16)

9.2 re.match( )函数:符合规则的字符必须出现在开始位置

import re
pat16='中.?传'
string16='数据科学与智能媒体学院中露露传数学专业传播学统计中间传来了呼唤中传CUC大学中房传'
ret16=re.match(pat16,string16)#因为规则没有出现在string16的开始位置,match()函数直接停止匹配,没有输出结果
print(ret16)
None
import re
pat16='中.?传'
string18='中c传数据科学与智能媒体学院中露露传数学专业传播学统计中间传来了呼唤中传CUC大学中房传'
ret18=re.match(pat16,string18)#规则出现在string16的开始位置,match()函数可以匹配
print(ret18)

9.3 全局匹配函数:re.compile(规则pat).findall(待搜索的字符串string)。可以输出所有的匹配结果

import re
pat16='中.?传'#该规则是懒惰模式:开始是中,结束是传,中间.?表示匹配出现1次的除了换行符以外的一个字符
string16='数据科学与智能媒体学院中露露传数学专业传播学统计中间传来了呼唤中传CUC大学中房传'
ret19=re.compile(pat16).findall(string16)
print(ret19)
['中间传', '中传', '中房传']

10.常见正则实例:匹配.com或.cn网址

import re
pat20='[a-zA-Z]+://[^\s]*[.com|.cn]'
string20='hasghj'
ret20=re.compile(pat20).findall(string20)
print(ret20)
['http://www.baidu.com']

11.简单的爬虫:豆瓣阅读的所有的出版社信息,并保存为txt

要爬取的网页为 https://read.douban.com/provider/all

#1.调用模块
import re
import urllib.request

#2.读取网页信息并解码
ur1='https://read.douban.com/provider/all'
data=urllib.request.urlopen(ur1).read().decode('utf-8','ignore')

#3.采用正则表达式提取目标内容
pat1 = '
(.*?)
'
#懒惰模式,按照网页格式设置 rst1 = re.compile(pat1).findall(data) #4.爬取到的出版社信息保存到本地txt file = open('F:\jupyterpycodes\python_pachongfenxi\爬取的豆瓣出版社信息.txt','w',encoding='utf-8') for i in range(0,len(rst1)): file.write(rst1[i] + '\n') print("写入成功!") file.close()
写入成功!

13. 爬取豆瓣阅读网站的所有出版社信息以及每个出版社出售作品的数量,并将其保存在txt文件以及sqlite数据库中

import re
import urllib.request
import sqlite3

#2.读取网页信息并解码
ur1=‘https://read.douban.com/provider/all’
data=urllib.request.urlopen(ur1).read().decode(‘utf-8’,‘ignore’)

#3.采用正则表达式提取目标内容
pat1 = ‘

(. ?)

pat2 = '
(.?) 部作品在售

rst1 = re.compile(pat1).findall(data)
rst2 = re.compile(pat2).findall(data)
rst = zip(rst1,rst2)

#4.存储txt文件
with open(‘demo1.txt’,‘w’) as fh:
for i,j in rst:
line = i + ’ ,’ + j +’\n’
fh.write(line)
#5.存储sqlite数据库
conn = sqlite3.connect(‘demo1.db’)
curs = conn.cursor()
curs.execute(’’’
CREATE TABLE publish (
publisher TEXT,
num INTEGER
)
‘’’)
query = ‘INSERT INTO publish VALUES (?,?)’
for line in open(‘demo1.txt’):
line = line.split(’,’)
curs.execute(query,line)


你可能感兴趣的:(Python爬虫)