php用正则表达抓取网页中文章(网络爬虫简单的解释就是抓取网站上的信息等)
优采云 发布时间: 2021-12-14 03:07php用正则表达抓取网页中文章(网络爬虫简单的解释就是抓取网站上的信息等)
大家好!本篇文章主要讲一些爬虫需要注意的地方,开发环境,使用正则表达式抓取网站的信息等。
一、简介
网络爬虫的简单解释就是从网站获取相关信息是一种已经使用的自动化处理方式;
1.1 合法性
《网络安全法》虽然在2017年已经开始实施,但是对于抓取公共信息的行为是否违法还不是特别清楚。
小编搜了一下资料,总结了两点:
1.2 检查robots.txt文件
你可以查看网站的robots.txt文件。这个文件对爬虫有什么限制?检查robots.txt文件可以将爬虫被拦截的可能性降到最低,你可能会发现网站界面相关的线索;
知乎
csdn网站
开源中国网站
操作说明:
并非所有 网站 都有 robots.txt 文件。大家要注意爬取,避免网站服务器过载、宕机等风险。
二、开发环境
2.1 个 Python3.8
大家尽量使用Python3.x 版本。
2.2 VSCode 开发工具
VSCode环境搭建看之前的推文
在使用python的时候,会使用pip install xxx命令安装一些包,会遇到安装不上的情况。我总结了解决方法供大家参考。
尝试使用管理员打开cmd或者vscode在python安装路径下进行安装,比如
C:\Users\64385\AppData\Local\Programs\Python\Python38>指定国内下载源下载。很多资源都在国外。如果直接下载,会出现网速问题。指定国内镜像源。很快,比如:
pip 安装 BeautifulSoup4
-i /simple/ --trusted-host 三、 正则表达式
3.1 个元字符^
如果 ^ 元字符放在 [] 字符集中,则表示反向
import re
str="python知识学堂,python欢迎你"
result=re.findall('[^python]',str)#反取 匹配除‘python’以外的字符 返回值是list
print(result)
结果:
3.2 个元字符*
表示匹配前面的字符 0 次或多次
import re
str="python知识学堂,欢迎来到学堂"
print(re.findall("知识*",str)) #星号前面的一个字符可以是0次或多次,返回值是list
print(re.findall("学堂*",str)) #星号前面的一个字符可以是0次或多次,返回值是list
结果:
3.3 个元字符 ()
也就是组匹配,()里面是一个组或者整个
import re
str="python知识学堂,欢迎来到学堂"
print(re.findall("(知识)",str))
print(re.findall("(学堂)",str))
结果:
这里列出了常用的,让我们自己尝试一下
3.4 常用元字符
3.5 个常用量词
也可以查看以下网站查看学习
/2/howto/regex.html
四、re 模块4.1 re 函数参数说明4.2 re.findall(pattern,string,flags=0)
返回字符串的唯一模式的匹配列表。从左到右扫描字符串,并按照找到的顺序返回匹配项。如果样式中有一个或多个组,则返回组合列表;它是一个元组列表(如果样式中有多个组合)。空匹配也将收录在结果中。
import re
text="python知识学堂,python欢迎你"
print("输入结果:")
print(re.findall(r'[a-z]',text)) #查找所有小写的字母
结果:
4.3 re.search(pattern,string,flags=0)
扫描整个字符串,找到匹配模式的第一个位置,并返回一个对应的匹配对象。如果没有匹配,则返回 None;请注意,这与查找零长度匹配不同。
import re
text="python知识学堂,python欢迎你"
print("输入结果:")
print(re.search(r'[a-z]',text).group()) #只会匹配一个对象
结果:
4.4 re.match(pattern,string,flags=0)
如果 string 开头的 0 个或多个字符与正则表达式模式匹配,则返回相应的匹配对象。如果没有匹配,则返回 None;请注意,它与零长度匹配不同。
import re
text="python知识学堂,python欢迎你"
print("输入结果:")
print(re.match(r'[a-z]',text).group()) #只会匹配一个对象
结果:
4.5 标志参数
举例说明如何使用该参数。
import re
text="python知识学堂,PYTHON欢迎你"
print("输入结果:")
print(re.findall('[a-z]',text,re.I)) #获取所有字母不管大小写
结果:
可以看到有些地方添加了前缀'r'。在带有前缀“r”的字符串文字中,表示不需要以任何特殊方式处理反斜杠。例如,r"\n" 表示收录'\' 和'n' 两个字符的字符串,而"\n" 表示仅收录一个换行符的字符串。建议您习惯性地加上前缀'r'。
这里只介绍常用的功能,还有一些其他的功能。可以自己上网查资料,自己学习。以下是官网,大家可以参考
/zh-cn/3/library/re.html
我们用正则的方法去抓取网站上的信息
五、定期抓拍
我们将使用 re(正则表达式)模块和请求(http)模块。这里我们使用更高效的 requests 库而不是 urllib 库。urllib库的使用方法可以百度。re 模块是python独有的,不需要安装。requests 需要安装如下
pip 安装请求
下面将使用正则表达式的方法,一步一步教你抓取网页的信息。
以/tjsj/tjbz/tjyqhdmhcxhfdm/2019/网站为例,抓取最新省份为例。
5.1 F12 或右键查看
F12或右键查看网站的元素,找到需要信息的位置,观察,如下图
点击红色箭头位置,在网页上选择您需要的信息,即可快速定位;
如图,可以看到我们需要的信息的位置和一些特征。可能这需要大家了解一点前端知识。现在开始在网站上抓取省份信息。
5.2 第一次爬取
import re
import requests
class demo():
def __init__(self):
try:
response=requests.get("http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2019/")
html=response.text #获取页面的html
print(html)
except:
print('出错了')
if __name__ == '__main__':
demo()
结果:
可以看到页面上的信息已经获取到了,但是好像有点乱码。
原因是没有设置编码方式
5.3 秒抓取
import re
import requests
class demo():
def __init__(self):
try:
response=requests.get("http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2019/")
response.encoding='gb2312' #编码转换
html=response.text #获取页面的html
print(html)
except:
print('出错了')
if __name__ == '__main__':
demo()
结果:
可以看到网页上的信息已经完全获取了。
大家想想我这里为什么用'gb2312'而不是'utf-8'?
这个要看网站,你怎么知道网站是什么编码?右键查看网页源码,见下图
圈出的是网站的编码方式。
那么下面将从获取到的网页的完整信息中提取出我们需要的信息。
5.4 第三次爬取
要获得想要的省份信息,首先要观察省份信息所在位置的特征。
可以看到省份信息在td标签中,td标签收录一个a标签,a标签收录下一页的链接地址。我们首先只获取省份信息。
import re
import requests
class demo():
def __init__(self):
try:
response=requests.get("http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2019/")
response.encoding='gb2312' #编码转换
html=response.text #获取页面的html
provincelist=re.findall(r"(.*?)
</a>",html)
for p in provincelist:
print(p)
except:
print('出错了')
if __name__ == '__main__':
demo()
结果:
可以获取所有省份的信息。
如果我们还想获取二级城市的数据,那么就得获取a标签中的下级地址,还要在二级页面查看我们想要的信息的位置和特征(同省,不重复)。
import re
import requests
import time
class demo():
def __init__(self):
try:
base_url='http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2019/'
response=requests.get(base_url)
response.encoding='gb2312' #编码转换
html=response.text #获取页面的html
provincelist=re.findall(r"(.*?)
</a>",html)
provinceUrls=re.findall(r"<a href='(.*?)'>.*?
</a>",html)
#for p in provincelist:
# print(p)
for u in provinceUrls:
#print(u)
cityurl=base_url+u
res=requests.get(cityurl)
res.encoding='gb2312' #编码转换
reshtml=res.text #获取页面的html
citylist=re.findall(r"(.*?)</a>",reshtml)
for c in citylist:
print(c)
time.sleep(0.5)
except:
print('出错了')
if __name__ == '__main__':
demo()
顺便也得到了二级城市的区号。大家应该也看到了,代码中有一个time.sleep函数,指的是以秒为单位的延迟。由于网站没有robots.txt信息,爬取信息时需要注意请求间隔。
所以仔细看看网站的信息特征,不难发现,如果我们一层一层往下看,会得到所有省市街道的最新信息,这样我们就可以方便获取省市最新信息。你可以自己试试。
六、总结
这是爬虫的第一条推文。本文主要为大家介绍爬虫中需要注意的事项,使用vscode开发环境时会遇到的问题,以及使用正则表达式获取省市的简单方法。使用常规方法抓取网页信息相对简单。多多练习,希望大家都能顺利爬行。