入门python(第十篇)爬虫&正则表达式&HTTP
(一)正则表达式
正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符"),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式(规则)的文本。
许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正则表达式引擎。正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开来的,后来在广泛运用于Scala 、PHP、C# 、Java、C++ 、Objective-c、Perl 、Swift、VBScript 、Javascript、Ruby 以及Python等等。正则表达式通常缩写成“regex”,单数有regexp、regex,复数有regexps、regexes、regexen。
常用于网页爬虫,文稿整理,数据筛选等。
简单的正则
在字符串中找到特定的子字符串
- 在线测试工具:
【1】:https://c.runoob.com/front-end/854/ - 匹配规则:
【1】:https://www.runoob.com/regexp/regexp-rule.html
【2】:https://www.w3cschool.cn/zhengzebiaodashi/regexp-syntax.html
import re
str = "dog runs to cat"
part1 = "dog"
part2 = "bird"
# 普通实现方法
print("dog" in str)
# 正则处理方法
print(re.search(part1,str)) # <re.Match object; span=(0, 3), match='dog'>
print(re.search(part2,str)) # None
使用表达式匹配(重要)
根据正则表达式的语法规则,写出表达式,可以进行匹配。而正则语法规则无需记忆。需要用的时候去查找。
part = r"r[au]n"
# 字符串前面的r表示正则表达式,并非普通的string
# 后面的匹配规则意思为ran或者run均可匹配
part1 = r"r[a-z]n"
# [a-z]表示为任何的小写字母
part2 = r"r[0-9a-z]n"
# [0-9a-z]表示为任何的小写字母或者0-9的数字
part3 = r"r[0-9A-Z]n"
# [0-9A-Z]表示为任何的大写字母或者0-9的数字
print(re.search(part,str)) # <re.Match object; span=(4, 7), match='run'>
print(re.search(part1,str)) # <re.Match object; span=(4, 7), match='run'>
print(re.search(part2,str)) # <re.Match object; span=(4, 7), match='run'>
print(re.search(part3,str)) # None
string = """
I love you,
you love me,
MX icecream and tea
"""
print(re.search(r"^MX",string)) # None
print(re.search(r"^MX",string,flags = re.M)) #<re.Match object; span=(26, 28), match='MX'>
(二)HTTP & 爬虫
超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII形式给出;而消息内容则具有一个类似MIME的格式。这个简单模型是早期Web成功的有功之臣,因为它使开发和部署非常地直截了当。
例如:URL = https://www.baidu.com/xxxxx:8080
统一资源定位系统(uniform resource locator;URL)是因特网的万维网服务程序上用于指定信息位置的表示方法。它最初是由蒂姆·伯纳斯·李发明用来作为万维网的地址。现在它已经被万维网联盟编制为互联网标准RFC1738。
超文本传输协议:HTTP、HTTPS
文件传输协议:FTP
万维网:WWW
域名:baidu.com。全球唯一,与IP地址之间映射。通过域名找到服务器。
参数:就是后面的一长串信息了
端口号::8080
信息送到服务器的哪个端口,一般情况下不写。有默认值。
下面是简单类型的网页爬虫:找到网页报道中的内容。
from urllib.request import urlopen
from bs4 import BeautifulSoup as bs
web_url = r"https://baijiahao.baidu.com/s?id=1742172765744995496"
html = urlopen(web_url,).read().decode("utf-8")
# print(html)
# 解析网页
soup = bs(html,features="lxml")
# 找到所有的P标签
all_p = soup.find_all("p")
# print(all_p)
# 找到所有的title
all_title = soup.find_all("title")
# print(all_title)
# 获取p标签里面的内容
for i in all_p:
print(i.get_text()+"\n")
第二个小例子:查找天气预报。
from urllib.request import urlopen
from bs4 import BeautifulSoup as bs
html = urlopen(r"http://www.weather.com.cn/weather/101270101.shtml").read().decode("utf-8")
# print(html)
soup = bs(html,features="lxml")
all_ul = soup.find_all("ul")
all_li = all_ul[2].find_all("li")
data = []
# 爬取近七天的天气预报
for i in all_li:
temper = {"day":"","weather":"","temperature":"","wind":""}
li_h = i.find("h1").get_text()
li_wea = i.find("p",attrs={"class":"wea"}).get_text()
win = i.find("p",attrs={"class":"win"}).find("i").get_text()
li_tem = i.find("p",attrs={"class":"tem"})
tem1 = li_tem.find_all("span")
if len(tem1)==0: tem1="0"
else: tem1 = tem1[0].text
tem2 = li_tem.find("i")
if len(tem2)==0: tem2="0"
else: tem2 = tem2.text
temper["day"] = li_h
temper["temperature"] = tem1+" —— "+tem2
temper["weather"] = li_wea
temper["wind"] = win
data.append(temper)
print("-----------------------------")
print("日期:",temper["day"])
print("天气:",temper["weather"])
print("温度:",temper["temperature"])
print("风力:",temper["wind"])