python 网页爬虫 基础篇
首先要连接自己的数据库
import pymysql import requests #需要导入模块 db = pymysql.connect('localhost', 'root', '*********', 'mysql')#第三个是数据库密码,第四个是数据库名称 print("数据库连接成功!") print("---------------------------------------------------") r = requests.get("https://python123.io/ws/demo.html")#获取网页源代码 print(r.text)
几个基本操作
r = requests.get("https://python123.io/ws/demo.html")#获取网页源代码 print(r)#输出该网页请求是否成功,成功输出<Response [200]> print(r.text)# 以文本形式输出网页源代码(格式和网页源代码一样) print(r.content)#以二进制形式输出源代码(没有换行和空格) print(r.encoding)# 输出网页编码方式 print(r.apparent_encoding)#和r.encoding功能相同,但更为精准 print(r.status_code)# 打印状态码, HTTP请求的返回状态,200表示连接成功,404表示失败 print(r.raise_for_status())# 若正常捕获网页内容,输出 None表示无异常
import re库
一、re.search(匹配规则,要匹配的字符串名称)
功能:扫描整个字符串返回第一个成功匹配的结果
result.group()获取匹配的结果
result.span()获去匹配字符串的长度范围
re.group(1)获取第一个括号中匹配的结果
import pymysql import requests #需要导入模块 db = pymysql.connect('localhost', 'root', '********', 'mysql')#第三个是数据库密码,第四个是数据库名称 print("数据库连接成功!") print("---------------------------------------------------") r = requests.get("https://python123.io/ws/demo.html")#获取网页源代码 import re def get_text(url):#函数 r = requests.get(url) r.raise_for_status() r.encoding = r.apparent_encoding return r.text print("-------------1-------------") print(get_text('https://python123.io/ws/demo.html'))#输出网页源代码 demo = get_text('https://python123.io/ws/demo.html')#类似于数组赋值 #demo类似于一个数组名字 result = re.search('Th.*?ge', demo)#赋值 print("-------------2-------------") print(result)#输出匹配字符串的长度范围和匹配的结果 print("-------------3-------------") print(result.group())#只输出获取匹配的结果 print("-------------4-------------") print(result.span())#输出获取匹配字符串的长度范围
输出
-------------1------------- <html><head><title>This is a python demo page</title></head> <body> <p class="title"><b>The demo python introduces several python courses.</b></p> <p class="course">Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses: <a href="http://www.icourse163.org/course/BIT-268001" class="py1" id="link1">Basic Python</a> and <a href="http://www.icourse163.org/course/BIT-1001870001" class="py2" id="link2">Advanced Python</a>.</p> </body></html> -------------2------------- <re.Match object; span=(19, 45), match='This is a python demo page'> -------------3------------- This is a python demo page -------------4------------- (19, 45) -------------5------------- ['<p class="title"><b>The demo python introduces several python courses.</b></p>', '<p class="course">Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:\r\n<a href="http://www.icourse163.org/course/BIT-268001" class="py1" id="link1">Basic Python</a> and <a href="http://www.icourse163.org/course/BIT-1001870001" class="py2" id="link2">Advanced Python</a>.</p>'] Process finished with exit code 0
二、re.match(匹配规则,要匹配的字符串名称,匹配成功返回值)
功能:re.match()功能和re.search()一样,但是强调从字符串的起始位置匹配一个模式,如果不是起始位置匹配的话,match()就会返回None
一般使用re.search(),不用re.match()
语法格式:
re.match(pattern,string,flags=0)
三、re.findall(匹配规则,要匹配的字符串名称,re.s)---------re.s是输出回车换行,匹配到一个结果,输出一个换行
功能:搜索字符串,以列表(list)的形式返回全部能匹配的子串-------->print(result)
import re html = '''<div id="songs-list"> <h2 class="title">经典老歌</h2> <p class="introduction"> 经典老歌列表 </p> <ul id="list" class="list-group"> <li data-view="2">一路上有你</li> <li data-view="7"> <a href="/2.mp3" singer="任贤齐">沧海一声笑</a> </li> <li data-view="4" class="active"> <a href="/3.mp3" singer="齐秦">往事随风</a> </li> <li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li> <li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li> <li data-view="5"> <a href="/6.mp3" singer="邓丽君">但愿人长久</a> </li> </ul> </div>''' results = re.findall('<li.*?href="(.*?)".*?singer="(.*?)">(.*?)</a>', html, re.S) print(results)#不换行输出所有匹配的内容 print(type(results))#type(results)返回results的数据类型(列表list) for result in results: print(result)#以列表形式输出所有匹配内容,包括括号 print(result[0], result[1], result[2])#以列表形式依次返回 括号内 匹配的内容,不包括括号
输出结果
[('/2.mp3', '任贤齐', '沧海一声笑'), ('/3.mp3', '齐秦', '往事随风'), ('/4.mp3', 'beyond', '光辉岁月'), ('/5.mp3', '陈慧琳', '记事本'), ('/6.mp3', '邓丽君', '但愿人长久')] <class 'list'> ('/2.mp3', '任贤齐', '沧海一声笑') /2.mp3 任贤齐 沧海一声笑 ('/3.mp3', '齐秦', '往事随风') /3.mp3 齐秦 往事随风 ('/4.mp3', 'beyond', '光辉岁月') /4.mp3 beyond 光辉岁月 ('/5.mp3', '陈慧琳', '记事本') /5.mp3 陈慧琳 记事本 ('/6.mp3', '邓丽君', '但愿人长久') /6.mp3 邓丽君 但愿人长久 [Finished in 0.1s]
几种匹配规则:
1、泛匹配
^:开始匹配标志
$:匹配结束标志
import re content= "hello 123 4567 World_This is a regex Demo" result = re.match("^hello.*Demo$",content) print(result) print(result.group()) print(result.span())
输出
<re.Match object; span=(0, 41), match='hello 123 4567 World_This is a regex Demo'> hello 123 4567 World_This is a regex Demo (0, 41) [Finished in 0.1s]
2、目标匹配
如果为了匹配字符串中具体的目标,则需要通过()括起来,()内就是要匹配输出的内容:
import re content= "hello 1234567 World_This is a regex Demo" result = re.match('^hello\s(\d+)\sWorld.*Demo$',content) print(result) print(result.group()) print(result.group(1)) print(result.span())
输出
<re.Match object; span=(0, 40), match='hello 1234567 World_This is a regex Demo'> hello 1234567 World_This is a regex Demo 1234567 (0, 40) [Finished in 0.1s]
3、贪婪匹配
.* :尽可能多的匹配非目标字符,将输出目标字符长度匹配到最小
.*? :尽可能少的匹配非目标字符,将输出目标字符长度匹配到最大
注:按目标类型分界
.* :
import re content= "hello 1234567 World_This is a regex Demo" result= re.match('^hello.*(\d+).*Demo',content) print(result) print(result.group(1))
输出
<re.Match object; span=(0, 40), match='hello 1234567 World_This is a regex Demo'> 7 [Finished in 0.1s]
.*? :
import re content= "hello 1234567 World_This is a regex Demo" result= re.match('^hello.*?(\d+).*Demo',content) print(result) print(result.group(1))
输出
<re.Match object; span=(0, 40), match='hello 1234567 World_This is a regex Demo'> 1234567] [Finished in 0.1s
4、常规匹配(比较繁琐,不常用)
import re content= "hello 123 4567 World_This is a regex Demo" result = re.match('^hello\s\d\d\d\s\d{4}\s\w{10}.*Demo$',content) print(result)#输出源代码 print(result.group())#输出匹配内容 print(result.span())#输出匹配代码的长度
输出
<re.Match object; span=(0, 41), match='hello 123 4567 World_This is a regex Demo'> hello 123 4567 World_This is a regex Demo (0, 41) [Finished in 0.1s]
正则表达式
常用的匹配模式: \w 匹配字母数字及下划线 \W 匹配f非字母数字下划线 \s 匹配任意空白字符,等价于[\t\n\r\f] \S 匹配任意非空字符 \d 匹配任意数字 \D 匹配任意非数字 \A 匹配字符串开始 \Z 匹配字符串结束,如果存在换行,只匹配换行前的结束字符串 \z 匹配字符串结束 \G 匹配最后匹配完成的位置 \n 匹配一个换行符 \t 匹配一个制表符 ^ 匹配字符串的开头 $ 匹配字符串的末尾 . 匹配任意字符,除了换行符,re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符 [....] 用来表示一组字符,单独列出:[amk]匹配a,m或k [^...] 不在[]中的字符:[^abc]匹配除了a,b,c之外的字符 * 匹配0个或多个的表达式 + 匹配1个或者多个的表达式 ? 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式 {n} 精确匹配n前面的表示 {m,m} 匹配n到m次由前面的正则表达式定义片段,贪婪模式 a|b 匹配a或者b () 匹配括号内的表达式,也表示一个组 [\u4e00-\u9fa5] :匹配中文 (\d{4}-\d{2}-\d{2}) : 匹配日期 .*? :匹配任意字符串 \[(\d{4}-\d{2}-\d{2})\] 匹配时间 eg:[2019-03-12] for content in contents: try: # 替换文本 s = str(content).replace('y,','')#.replace('<', '-5') s = s.replace('年', '-').replace('月', '-').replace('日', '') s = s.replace('(', '').replace(')', '').replace('\'', '') content = s.split(',') # s = str(content).replace('/','-') # # s = re.sub('(\d{4}-\d{2})',r'\1-',s) # s = s.replace('(', '').replace(')', '').replace('\'', '') # content = s.split(',') list.append(content) except EOFError as e: print(e) continue return list
正则表达式匹配练习
1、匹配猫眼电影top100的电影名、主演、上映日期
对应正则表达式:'class="name".*?title="(.*?)".*?:(.*?)\s*?</p>.*?:(\d{4}-\d{2}-\d{2})'
2、匹配猫眼电影top100的海报图片
对应的正则表达式:'img\sdata-src="(.*?)"\salt'
3、匹配西南大学计算机学院讲座信息
'<li><span\sclass="fr">\[(\d{4}-\d{2}-\d{2})\].*? (.*?)</a></li>',
等风起的那一天,我已准备好一切