一、正则表达式
正则表达式就是从一个字符串中提取出需要的字符串,或者说是按照某种规则去匹配字符串
在python中使用正则表达式,需要先引入一个正则表达式模块re,经常用到的函数是findall()
findall(pattern,string,flags=0)
pattern: 用哪种规则提取
string: 从哪个字符串进行提取
flags: 可选,控制匹配方式
返回的是一个列表
pattern
正则表达式的规则很多,在这里就介绍其中一些常用的
1). 匹配某个字符前面或者后面的一个字符
import re
str1='abcdefg'
result=re.findall('b.',str1)
print(result) #['bc']
result=re.findall('.b',str1)
print(result) #['ab']
2) ()只匹配与()中的一样的字符
import re
str1='abcdefg'
result=re.findall('b(.)',str1)
print(result) #['c']
3)\w 匹配数字,字母,下划线
\W 匹配非数字,字母,下划线,即跟\w相反
import re
str1='hd#ow@e2%4_='
result=re.findall('\w',str1)
print(result) #['h', 'd', 'o', 'w', 'e', '2', '4', '_']
result=re.findall('\W',str1)
print(result) #['#', '@', '%', '=']
4)\s 匹配空格,换行符,制表符
\S 匹配非空格,换行符,制表符
import re
str1=' wu ed\td!!!\n '
result=re.findall('\s',str1)
print(result) #[' ', ' ', ' ', ' ', ' ', '\t', '\n', ' ', ' ', ' ']
result=re.findall('\S',str1)
print(result) #['w', 'u', 'e', 'd', 'd', '!', '!', '!']
5){n} 匹配出现n次的字符
{n,m} 匹配出现n≤次数≤m的尽可能多的字符
import re
str1=' wu ed\td!!!\n '
result=re.findall('\s{3}',str1)
print(result) #[' ', '\n ']
result=re.findall('\S{3}',str1)
print(result) #['d!!']
result=re.findall('\s{3,4}',str1)
print(result) #[' ', '\n ']
result=re.findall('\S{2,3}',str1)
print(result) #['wu', 'ed', 'd!!']
6)[] 匹配[]中的任意字符,[]是一个范围
[^] 匹配非[]中的任意字符
import re
str1='wd283dwk(3%je'
result=re.findall('[a-z]',str1)
print(result) #['w', 'd', 'd', 'w', 'k', 'j', 'e']
result=re.findall('[^a-z]',str1)
print(result) #['2', '8', '3', '(', '3', '%']
7)* 匹配*之前的的0或多个字符
import re
str1='abcabbbbbadefg'
result=re.findall('ab*',str1) #匹配a后面有0个b,或者多个b
print(result) #['ab', 'abbbbb', 'a']
8)?匹配?之前的0个或1个字符
import re
str1='abcabbbbbadefg'
result=re.findall('ab?',str1) ##匹配a后面有0个b,或者1个b
print(result) #['ab', 'ab', 'a']
9)+ 匹配+之前的多个字符,不包括0个
import re
str1='abcabbbbbadefg'
result=re.findall('ab+',str1)
print(result) #['ab', 'abbbbb']
10)^从开头匹配
$从结尾匹配
import re
str1='abcdefg'
result=re.findall('^ab',str1)
print(result) #['ab']
result=re.findall('ef$',str1)
print(result) #[]
flags
re.I是不区分大小写,re.S是匹配多行字符串
import re
str1='''abcdefg
Abcdefg'''
result=re.findall('ab.',str1)
print(result) #['abc']
result=re.findall('ab.',str1,re.I)
print(result) #['abc', 'Abc']
str2='''abcdefg
Abcdefg
h'''
result=re.findall('ab.*h',str2)
print(result) #[]
result=re.findall('ab.*h',str2,re.S)
print(result) #['abcdefg\nAbcdefg\nh']
贪婪匹配和懒惰匹配
贪婪匹配:.* 尽可能多的匹配符合规则的字符串
懒惰匹配:.*? 尽可能少的匹配符合规则的字符串
import re
str1='''abcdefgabcdefgabc'''
result=re.findall('a.*c',str1)
print(result) #['abcdefgabcdefgabc']
result=re.findall('a.*?c',str1)
print(result) #['abc', 'abc', 'abc']
二、爬虫
爬虫简单来说就是抓取网页上出现的各种数据
我们知道一个网页地址(URL)都是http或者https开头(遵循http或https协议),打开网页后,网页的内容是用HTML语言展示的(可以在网页上右键-查看页面源代码或者按F12打开开发工具就可以查看,关于这个语言的语法,网络上有很多教程可供参考),爬虫就是通过请求网页,得到网页源码,然后通过解析源码,获得我们所需要的数据
以从晋江文学城爬一本书的目录和链接为例:
import re
import requests #要在python中访问网页,需要加载requests模块
import xlwt #加载excel的写入模块
url = 'https://www.jjwxc.net/onebook.php?novelid=1675838' #待爬取的书的网址
req = requests.get(url) #获取网页内容
#print(req) #<Response [200]> 返回响应码
#print(req.text) #返回网页的html
req.encoding = 'gbk' #将编码转为GBK,防止乱码
book_name = re.findall('<span itemprop="articleSection">(.*?)</span>', req.text)[0] #获取书名,不需要列表,只需要列表中的元素
#print(book_name)
chapter_name = re.findall('novelid=1675838&chapterid=.*?">(.*?)</a>', req.text) #获取章节名称
#print(chapter_name)
chapter_id = re.findall('novelid=1675838&chapterid=(.*?)">', req.text) #获取章节id
#print(chapter_id)
dict1 = {} #定义一个字典存放章节名和章节链接
for i in range(len(chapter_id)):
dict1[chapter_name[i]] = f'{url}&chapterid={chapter_id[i]}' #将章节作为键,章节链接作为值
excel1 = xlwt.Workbook() #实例化一个excel
worksheet = excel1.add_sheet(f'{book_name}') #定义sheet名称
worksheet.write(0, 0, '序号') #将‘序号’写入第0行,第0列
worksheet.write(0, 1, '章节') #将‘章节’写入第0行,第1列
worksheet.write(0, 2, '链接') #将‘链接’写入第0行,第2列
row = 1
for k, v in dict1.items(): #遍历字典中的键值对
worksheet.write(row, 0, chapter_id[row-1]) #在第row行,第0列按顺序写入序号
worksheet.write(row, 1, k) #在第row行,第1列按顺序写入键,即章节名
worksheet.write(row, 2, v) #在第row行,第2列按顺序写入键,即章节链接
row += 1 #上一行写完后+1,继续写下一行
excel1.save(f'c:/{book_name}.xls') #将excel保存到电脑中
执行上述代码,在c盘生成了一个新的excel