Python爬虫学习

一、爬虫

说到爬虫不得不说 python,因为我学 python 很大一部分原因是因为爬虫,爬虫之前有新闻报道,说爬虫犯法了,但不能不说爬虫是个好东西,只要我们在法律允许的范围内,合理使用爬虫就好了

而我近期学习爬虫,将学习过程记录了下来,算是我学习爬虫的一个笔记吧,我看的是北京理工大学,嵩天副教授的 python网络爬虫与信息提取 的国家精品在线开放课程,讲的十分详细,我感觉不错

二、Requests 模块

1、安装requests

我们使用pip安装request模块,为了下载比较快,我们使用清华开源镜像库:https://pypi.tuna.tsinghua.edu.cn/simple/

pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple/

在这里插入图片描述

或者用pycharm打开project interpreter

在这里插入图片描述

搜索requests,选中后进行安装

在这里插入图片描述

2、HTTP协议

HTTP:超文本传输协议,是基于“请求与响应”模式的、无状态的应用层协议,采用URL作为定位网络资源的标识

URL: 格式http://host[:port][path]

* host: 合法的Internet主机域名或IP地址
* port: 端口号,缺省端口为80
* path: 请求资源的路径

HTTP的URL理解:

URL是通过HTTP协议存取资源的Internet路径,一个URL对应一个数据资源

HTTP协议对资源的操作:

方法说明
GET请求获取URL位置的资源
HEAD请求获取URL位置资源的响应消息报告,即获取该资源的头部信息
POST请求向URL的位置资源后附加新的数据
PUT请求向URL位置存储一个资源,覆盖原URL未知的资源
PATCH请求局部更新URL未知的资源,即改变该处资源的部分内容
DELETD请求删除URL位置存储的资源

requests 模块的主要方法

方法说明
requests.request()构造一个请求,支撑以下各方法的基础方法
requests.get(url)获取HTML网页的主要方法,对应HTTP的GET,获取网络资源
requests.head(url,get)获取HTML网页头部形式,对应HTTP的HEAD,以很少的流量获取资源的概要信息
requests.post(url, post,date)向HTML网页提交POST请求,对应HTTP的POST,向服务器提交新增数据
requesrs.put(url,put,date)向HTML网页提交PUT请求,对应HTTP的PUT,向服务器提交数据,覆盖旧的数据
requests.patch()向HTML网页提交局部修改请求,对应HTTP的PATCH
requests.delete()向HTML页面提交删除请求,对应HTTP的DELETE

requests 模块中的方法一一对应 http 协议对于资源的操作

3、requests模块主要方法

requests.request(method,url,**kwargs)
  • method : 请求方式,对应“GET”,“POST”,“PUT”,“DELETE”,“HEAD”,PATCH",OPTIONS"7种
  • url:拟获取页面的URL链接
  • **kwargs:控制访问参数,共13个
控制参数说明
params字典或者字节序列,作为参数增加到URL中
data字典或者字节序列或文件对象,作为Request的内容
headers字典,HTTP定制头
cookies字典或者CookieJar,Request中的cookie
auth元组,支持HTTP认证功能
files字典类型,传输文件
timeout设定超时时间,秒为单位
proxies字典类型,设定访问代理服务器,可以增加登录认证
allow_redirrectsTrue/Flase,默认为True,重定向开关
streamTrue/Flase,默认为True,获取内容立即下载开关
verifyTrue/Flase,默认为True,认证SSL证书开关
cert本地SSL证书路径
jsonJSON格式的数据,作为Request的内容
requests.get(url,params = None,**kwargs)
  • url : 拟获取页面的url连接
  • params : url的额外参数,字典或字节流格式,可选
  • **kwargs : 12个控制参数
requests.head(url,**kwargs)
  • url :拟获取页面的url
  • **kwargs:13个控制访问参数
requests.post(url,data=None,json=None,**kwargs)
  • url :拟更新页面的URL
  • data:字典、字节序列或文件,request的内容
  • json:JSON格式的数据,request的内容
  • **kwargs:11个控制访问参数
requests.put(url,data=None,**kwargs)
  • url:拟更新页面的url连接
  • data:字典、字节序列或文件,request的内容
  • **kwargs:12个控制访问参数
request.patch(url,data=None,**kwargs)
  • url:拟更新页面的URL
  • data:字典,字节序列或文件,request的内容
  • **kwargs:12个控制访问参数
request.delete(url,**kwargs)
  • URL :拟删除页面的URL连接
  • **kwargs:13个控制访问参数xs

4、request模块的 get() 方法

获取一个网页最简单的方法是使用

r = request.get(url)

给定get方法和url构造一个向服务器请求资源的request对象 ,返回包含服务器资源的Response对象,Response包含了所有资源

request.get(url,params=None,**kwargs)

  • url : 拟获取页面的URL连接
  • params :URL中的额外参数,字典或字节流格式,可选
  • **kwargs : 12个控制访问的参数,可选

在这里插入图片描述
Response 对象属性:

属性说明
r.status_codeHTTP 请求的返回状态,200表示连接成功,404表示连接失败
r.textHTTP 相应内容的字符形式,即,url对应的页面内容
r.encodingHTTP header 中猜测的响应内容的编码格式
r.apparent_encoding从内容中分析出的响应内容编码方式(备选编码方式)
r.contentHTTP 响应内容的二进制形式

r.encoding:如果header中不存在charset ,则认为编码为 ISO-8859-1

r.apparent_encoding: 根据网页内容分析出的编码方式

4、爬取网页的通用代码

爬取网页的通用代码框架

def getHTMLText(url):
	try:
		r = requests.get(url,timeout=30)
		r.raise_for_status()	#如果状态不是200,引发HTTPError异常
		r.encoding = r.apparent_encoding
		return r.text
	except:
		return "产生异常"
	

5、request 模块异常

异常说明
requests.ConnectionError网络连接异常,如DNS查询失败、拒绝连接等
requests.HTTPErrorHTTP 错误异常
requests.URLRequiredURL缺失异常
requests.TooManyRedirects超过最大重定向次数,产生重定向异常
requests.ConnectTimeout连接远程服务器超时异常
requests.Timeout请求URL超时,产生超时异常

理解Requests模块的异常

异常说明
r.raise_for_status()如果不是200,产生requests.HTTPError

三、BeautifulSoup 模块

1、安装BeautifulSoup 模块

使用命令pip install beautifulsoup4安装,或者使用pycharm安装

BeautifulSoup 是解析、遍历、维护“标签树”的功能库

引用 BeautifulSoup 常用from bs4 import BeautifulSoup

2、信息标记的三种形式

信息的标记

  • 标记后的信息可形成信息组织结构,增加了信息维度
  • 标记后的信息可用于通信、存储或展示
  • 标记的结构与信息一样具有重要价值
  • 标记后的信息跟有利于程序的理解和运用

HTML(hyper text markup language) 超文本标记语言,是WWW(world wide wed)的信息组织方式,能将声音 图像 视频等超文本信息嵌入到文本信息中。HTML通过预定义的<>...</>标签形式组织不同类型的信息

信息标记的三种形式:XML、JSON、YAML

XML:XML(eXtensible Markkup Language) :扩展标记语言与HTML类似,以标签为主来构建信息表达信息的方式,如果有信息就用一对<name>...</name>来表达信息,如果没有内容可以用</name>来表示,也可以用<!-- -->来表示注释

JSON:JSON(JavaScript Object Notation):JavaScript 语言中对面向对象信息的一种表达形式,简单来讲就是有类型的键值对 key: value,来构建的信息表达方式。“key”:“value”,是有数据类型的信息,当同一个键值有多个key时,可以使用"key":["value1","value2"...],键值对可以嵌套使用"key":{"newkey":"value"}

YAML:YAML(YAML Ain’t Markup Language):采用无类型的键值对来构建信息,key: value,用缩进来表达所属关系,如:

key :
	newkey:value
	olekey: value1

YAML 用-表示并列关系,如:

key :
-value1
-value2

YAML 用|来表示整块数据 #表示注释

三种信息标记形式的比较

XML 用<name>...</name>来表达信息,JSON用有类型的键值对来表示信息的,YAML是用无类型的键值对来表达信息的

XML:

<person>
	<fristName>Tim</fristName>
	<lastName>Song</lastName>
	<address>
		<streetAddr>xxx村xx号</streeAddr>
		<city>上海市</city>
	</address>
	<prof>Computer System</prof><prof>Security</prof>
</person>

JSON:

{
	"fristName" : "tim",
	"lsatName" : "song",
	"address" :{
		"streetAddr" : xxx村xx号,
		"city" : 上海市,
		"zipcode" : 10081
	},
	"prof" : ["computer System","Security"]
}

YAML:

fristName: Tim
LastName: Song
adress:
	streetAddr : xx村xx号
	City : 上海
	zipcode : 100081
prof:
-Computer System
_Security

XML:最早的通用信息标记语言,可扩展性好,但繁琐,在Internet上的信息交互于传递

JSON:信息有类型,适合程序处理(js),较XML简洁,用在移动应用云端和节点的信息通信中,没有注释,用在程序对接口的处理中

YAML:信息无类型,文本信息比例最高,可读性好,用在各类系统的配置文件中,有注释易读

3、信息提取的一般方法

**第一种:**完整解析信息的标记形式,再提取关键信息,XML,JSON,YAML,需要标记解析器,例如bs4库的标签树遍历,优点是信息解析准确,缺点是提取过程繁琐,速度慢

**第二种:**无视标记形式,直接搜索关键信息,对信息的文本利用查找函数查找就可以,优点是提取过程简单,缺点是提取结果准确性与信息内容相关,

**第三种:**融合方法,结合形式解析与搜索方法,提取关键信息,需要标记解析器及文本查找函数

4、BeautifulSoup解析

将获得到的网页资源进行解析,转换成容易识别的、标签类型的信息标记,为后续爬取做准备工作

解析器使用方法条件
bs4的HTML解析器BeautifulSoup(mk,“html.parser”)安装bs4
lxml的HTML解析器BeautifulSoup(mk,“lxml”)pip install lxml
lxml的XML解析器BeautifulSoup(mk,“xml”)pip install lxml
html5lib的解析器BeautifulSoup(mk,“html5lib”)pip install html5lib

基于bs4库的HTML格式化和编码

soup = BeautifulSoup(f.text,"html.parser")
print(soup.prettify())			# 打印通过格式化处理的html页面

prettify()将HTML的标签进行换行等处理,使得标签十分清晰,

bs4库将读入的HTML和其他字符串的编码转换为utf-8

import requests
from bs4 import BeautifulSoup

f = requests.get("https://www.baidu.com")
f.encoding = f.apparent_encoding
soup = BeautifulSoup(f.text,"html.parser")		# 解析获取到的信息,解析器为html.praser
print(soup.prettify())

5、BeautifulSoup类的基本元素

基本元素说明
Tag标签,最基本的信息组织单元,分别用<>和</>标明开头和结尾
Name标签的名字,<p>...</p>的名字是’p’,格式:<tag>.name
Attributes标签的属性,字典形式的组织,格式:<tag>:attrs
NavigableString标签内非属性字符串,<>...</>中字符串,格式:<tag>.string
Comment标签内字符串的注释部分,一种特殊的comment类型
import requests
from bs4 import BeautifulSoup

f = requests.get("https://www.baidu.com")
f.encoding = f.apparent_encoding
soup = BeautifulSoup(f.text,"html.praser")

print(soup.a.name)			# 获取 a 标签的名字
print(soup.a.attrs)			# 获取 a 标签的属性
print(soup.a.attrs["href"]) # 获取 a 标签内包含的链接信息(url)

运行结果:

a
{'href': 'http://news.baidu.com', 'name': 'tj_trnews', 'class': ['mnav']}
http://news.baidu.com

6、基于bs4模块的HTML内容遍历

标签树的下行遍历

属性说明
.contents子节点的列表,将<tag>所有儿子节点存入列表
.children子节点的迭代类型,与.contents类型,用于循环遍历儿子节点
.descendants子孙节点的迭代类型,包含所有子孙节点,用于循环遍历
soup = BeautifulSoup(f.text,"html.praser")
print(soup.head.contents)		# 遍历 head 的儿子标签,存入列表
print(len(soup.head.contents))	# 获得 head 的儿子标签的个数
print(soup.head.contents[1])	# 输出 head 的第一个儿子标签
for child in soup.body.children:		#遍历儿子标签
	print(child)		
for descendants in soup.body.descendants:	# 遍历子孙节点
	print(descendants)

标签树的上行遍历

属性说明
.parent节点的父亲标签
.parents节点先辈标签的迭代类型,用于循环遍历先辈标签
soup = BeautifulSoup(f.text,"html.parser")
print(soup.title.parent)	#打印 title 的父辈标签

遍历先辈标签

soup = BeautifulSoup(f.text,"html.parser")

for parent in soup.a.parents:		#遍历 a 标签的先辈标签
	if parent is None:
    	print(parent)
    else:
        print(parent.name)

标签树的平行遍历

属性说明
.next_sibling返回按照HTML文本顺序的下一个平行节点标签
.previous_sibling返回按照HTML文本顺序的上一个平行节点标签
.next_siblings迭代类型,返回按照HTML文本顺序的后续所有平行节点标签
.previous_siblings迭代类型,返回按照HTML文本顺序的前序所有平行节点标签

平行遍历发生在同一个父节点的各节点间,各平行标签不一定都是标签,有可能是 NavigableString

soup  = BeautifulSoup(f.test,"html.parser")
print(soup.a.next_sibling)		# 打印 a 标签的下一个平行标签
print(soup.a.previous_sibling)	# 打印 a 标签的上一个标签

标签树的平行遍历

for sibling in soup.a.next_siblings:	# 遍历 a 标签的下一个平行标签
    print(sibling)
for sibiling in soup.a.previous_siblings:	# 遍历 a 标签的上一个标签
	print(sibling)

7、基于bs4库的HTML内容查找方法

soup.find_all("a")			# 查找 a 标签
soup.finf_all(["a","b"])	# 查找 a b 标签

for tag in soup.find_all(True):	# 查找所有标签
	print(tag.name)
import re
for tag in soup.find_all(re.compile("b"))		# 查找所有以 b 开头的标签
	print(tag.name)

<>.find_all(name,attrs,recursive,string,**kwargs)

返回一个列表类型,存储查找结果

**name :**对标签名称的检索字符串

**attrs:**对标签属性值的检索字符串,可标注属性检索

**recursive:**是否对子孙全部检索,默认为True

string:<>...</>中字符串区域的检索字符

soup.fina_all('p','course')		# 查找还有course属性的P标签
soup.find_all(id="link")		# 查找 id="link" 的属性标签
import re
soup.find_all(id=re.compile("link"))	# 查找 id 含有 link 属性的标签
soup.find_all("a",recursive = Flase)	# 从soup 的根节点开始,儿子节点中没有 a 标签
soup.find_all(string="basic pyhton")	# 从soup中检索basic Pyhton
import re
soup.find_all(string=re.compile("python"))	# 检索所有含有Python字段的所有字符串域

<tag>(..)等价于<tag>.find_all(..)

soup(..)等价于soup.find_all(..)

soup的find方法扩展

方法说明
<>.find()搜索且只返回一个结果,字符串类型,同.find_all()参数
<>.find_parents()在先辈节点中搜索,返回列表类型,同.find_all()参数
<>.find_parent()在先辈节点中返回一个结果,字符串类型,同.find()参数
<>.find_next_siblings()在后续平行节点中搜索,返回列表类型,同.find_all()参数
<>.find_next_sibling()在后续平行节点中返回一个结果,字符串类型,同.find()参数
<>.find_previous_siblings()在前序平行节点中搜索,返回列表类型,同.find_all()参数
<>.find_previous_sibling()在前序平行节点中返回一个结果,字符串类型,同.find()参数
# 爬取最好大学网站的大学排名信息
import requests
import bs4

def getHTMLText(url):
   try:
       f = requests.get(url)
       f.raise_for_status()
       f.encoding = f.apparent_encoding
       return f.text
   except:
       print("异常")


def fillUnivList(ulist,html):

    soup = bs4.BeautifulSoup(html,"html.parser")
    for tr in soup.find("tbody").children:
        if isinstance(tr,bs4.element.Tag):
            tds = tr("td")
            ulist.append([tds[0].string, tds[1].string, tds[3].string])

def printUnivList(ulist,num):
    print("{:^10}\t{:^6}\t{:^10}".format("排名","学校名称","总分"))
    for i in range(num):
        u = ulist[i]
        print("{:^10}\t{:^5}\t{:^10}".format(u[0], u[1],u[2]))

if __name__=="__main__":
    uinfo = []
    url = "http://www.zuihaodaxue.com/Greater_China_Ranking2019_0.html"

    html = getHTMLText(url)
    fillUnivList(uinfo,html)
    printUnivList(uinfo,20)

输出结果:

    排名    	 学校名称 	    总分    
    1     	清华大学(北京)	   100    
    2     	北京大学 	   80.5   
    3     	香港中文大学	   71.0   
    4     	浙江大学 	   66.1   
    5     	香港大学 	   62.0   
    6     	中国科学技术大学	   61.4   
    7     	上海交通大学	   58.9   
    8     	复旦大学 	   56.8   
    9     	清华大学(新竹)	   56.5   
    10    	台湾大学 	   54.8   
    11    	北京师范大学	   53.9   
    12    	香港城市大学	   50.1   
    13    	香港科技大学	   49.8   
    14    	南京大学 	   46.9   
    15    	华中科技大学	   44.3   
    16    	中山大学(广州)	   43.9   
    17    	香港理工大学	   43.5   
    18    	交通大学(新竹)	   42.5   
    19    	哈尔滨工业大学	   42.0   
    20    	澳门科技大学	   41.9  

四、RE模块

1、正则表达式

正则表达式(regular expression regex RE):正则表达式是用来简洁表达一组字符串的表达式

py+ 表示p后面有几个或多个y的字符串

正则表达式特点:

  • 通用的字符串表达框架

  • 简洁表达一组字符串的表达式

  • 针对字符串表达“简洁”和“特征”思想的工具

  • 判断某字符串的特征归属

正则表达式在文本处理中十分常用

  • 表达文本类型的特征(病毒、入侵等)
  • 同时查找或替换一组字符串
  • 匹配字符串的全部或部分区域

正则表达式的使用:

编译:将符合正则表达式语法的字符串转换为正则表达式特征

正则表达式的语法:

P(Y|YT|YTH|YTHON)?N

正则表达式由字符和操作符构成

操作符说明实例
.表示任何单个字符
[]字符集,对单个字符给出排除范围[abc]表示a,b,c,[az]表示az单个字符
[^ ]非字符集,对单个字符给出排除范围[^abc]表示非a或非b或非c的单个字符串
*前一个字符0次或无限次扩展abc*表示ab,abc,abcc,abccc等
+前一个字符1次或 无限次扩展abc+表示abc,abcc,abccc等
前一个字符0次或1次 扩展abc?表示ab,abc
|左右表达式任意一个abc|def表示abc,def
{m}扩展前一个字符m次ab{2}c表示abbc
{m,n}扩展前一个字符m至n次(含n)ab{1,2}c表示abc,abbc
^匹配字符串开头^abc表示abc且在一个字符串的开头
$匹配字符串结尾abc$表示abc且在字符串结尾
()分组标记,内部只能使用|操作符(abc)表示abc,(abc|def)表示abc,def
\d数字,等价于[0-9]
\w单词字符,等价于[A-Za-z0-9]

经典正则表达式实例

^[a-za-z]+$			由26个字母组成的字符串
^[A-Za_z0-9]+$		由26个字母和数字组成的字符串
^-?\d+$				整数形式的字符串
^[0-9]*[1-9][0-9]*$ 正整数形式的字符串
[1-9]\d{5}			中国境内邮政编码,6位
[\u4e00=\u9fa5]		匹配中文字符
\d{3}-\d{8}|\d{4}-\d{7}		国内电话号码,010-68913536

匹配IP地址的正则表达式:IP地址字符串形式的正则表达式 IP地址分4段,每段0-255,\d+.\d+.\d+.\d+

\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3},这两个不精确,精确的(([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5]).){3}(1-9)?\d|1\d{2}|2[0-4]\d|25[0-5]

2、Re库的使用

Re库是Pyhton的标准库,主要用于字符串匹配,正则表达式是raw string类型(原生字符串类型),表示为r’text’,原生字符串类型是不包含转义符的字符串,也可以用string类型的,但更为复杂繁琐(因为有转义符)

Re库主要功能函数

函数说明
re.search()在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象
re.match从一个字符串的开始位置起匹配正则表达式,返回match对象
re.findall()搜索字符串,以列表形式返回全部能匹配的子串
re.split()将一个字符串按照正则表达式匹配结果进行分割,返回列表类型
re.finditer()搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象
re.sub()在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串
re.search(pattern,string,flags=0)
  • 在一个字符串类型中搜索匹配正则表达式的第一个位置,返回match对象
  • pattern:正则表达式的字符串或原生字符串表示
  • string:待匹配的字符串
  • flags :正则表达式使用时的控制标记

flags正则表达式使用时常用的控制标记

常用标记说明
re.I re.IGNORECASE忽略正则表达式的大小写,[A-Z]能匹配小写字符
re.M re.MULTILINE正则表达式中的^操作符能够将给定字符串的每行当做匹配开始
re.S re.DOTALL正则表达式中的 . 操作符能够匹配所有中字符,默认匹配除换行外的所有字符
import re
match = re,serach(r'[1-9]\d{5},"BIT 100081")
if match:
	print(match.group(0))
re.match(pattern,string,flags=0)
  • 从一个字符串的开始位置起匹配正则表达式,返回match对象
  • pattern:正则表达式的字符串或原生字符串表示
  • string:待匹配的字符串
  • flags :正则表达式使用时的控制标记
import re
match re,match(r'[1-9]\d[5]','100081 BIT')
if match:									#判断是否为空
	match.group(0)
re.findall(pattern,string,flags=0)
  • 搜索字符串,以列表形式返回 全部能匹配的子串
  • pattern:正则表达式的字符串或原生字符串表示
  • string:待匹配的字符串
  • flags :正则表达式使用时的控制标记
import re
ls = re.findall(r'[1-9]\d{5}','BIT100081 BIT100084')

re.split(pattern,string,maxsplit=0,flags=0)
  • 将一个字符串按照正则表达式匹配结果进行分割,返回列表类型
  • pattern:正则表达式的字符串或原生字符串表示
  • string:待匹配的字符串
  • maxsplit:最大分割数,剩余部分作为最后一个元素输出
  • flags :正则表达式使用时的控制标记
import re
re.split(r'[1-9]\d{5}','BIT10081 TUS100084')
re.split(r'[1-9]\d{5}','BIT10081 BIT100084',maxsplit = 1)

返回

['BIT','TUS',' ']
['BIT','TUS100084']
re.finditer(pattern,string,falgs=0)
  • 搜索字符串,返回一个匹配结果的迭代类型,每个迭代类型元素是match对象
  • pattern:正则表达式的字符串或原生字符串表示
  • string:待匹配的字符串
  • flags :正则表达式使用时的控制标记
import re
for m in re.finditer(r'[1-9]\d{5}','BIT100081 TSU100084'):
	if m:
		print(m.group(0))
re.sub(pattern,repl,string,count=0,flags=0)
  • 在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串
  • pattern:正则表达式的字符串或原生字符串表示
  • repl:替换匹配字符串的字符串
  • string:待匹配的字符串
  • count:匹配的最大替换次数
  • flags :正则表达式使用时的控制标记
import re
re.sub(r'[1-9]\d{5}',':zipcode','BIT100081 TUS100084')

返回

'BIT:zipcode TUS:zipcode'

Re的另一种等价用法

rst = re.search(r'[1-9]\d{5}','BIT 100081')		#函数式用法,一次调用

pat = re.compile(r'[1-9]\d{5}')
rst = pat.search('BIT 100081')		# 同样可以使用其他函数

regex = re.compile(pattern,flags=0)
  • 将正则表达式的字符串形式编译成正则表达式对象
  • pattern:正则表达式的字符串或原生字符串表示
  • flags:正则表达式使用时的控制标记
函数说明
regex.search()在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象
regex.match从一个字符串的开始位置起匹配正则表达式,返回match对象
regex.findall()搜索字符串,以列表形式返回全部能匹配的子串
regex.split()将一个字符串按照正则表达式匹配结果进行分割,返回列表类型
regex.finditer()搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象
regex.sub()在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串

3、match对象类型

match = rst = re.search(r'[1-9]\d{5}','BIT 100081')		
if match:
	print(match.group(0))
	type(match)

运行结果:

100081
<class '_sre.SRE_Match'>

match 对象属性:

属性说明
.string带匹配的文本
.re匹配时使用的pattern对象(正则表达式)
.pos正则表达式搜索文本的开始位置
.endpos正则表达式搜索文本的结束位置

match 对象的方法:

方法说明
.group()获取匹配后的字符串
.start()匹配字符串在原始字符串的开始位置
.end()匹配字符串在原始字符串的结束位置
.span()返回(.start()),(.end())
import re
match = re,serach(r'[1-9]\d{5},"BIT100081 TSU100084")
print(match.string)
print(match.re)
print(match.endpos)
print(match.pos)
print(match.group(0))
print(match.start())
print(match.end())
print(match.span())

运行结果:

'BIT100081 TSU100084'
re.compile('[1-9]\\d{5}')
19
0
'100081'
3
9
(3,9)

4、re库的贪婪匹配和最小匹配

re库默认采用贪婪匹配,即输出匹配最长的子串

match = re.search(r'PY.*N','PYANBNCNDN')
print(match.group(0))

输出结果:

'PYANBNCNDN'

最小匹配:

match = re.search(r'PY.*?N','PYANBNCNDN')
print(match.group(0))

输出结果:

'PYN'

最小匹配操作符

操作符说明
*?前一个字符0次或无限次扩展,最小匹配
+?前一个字符串1次或无限次扩展,最小匹配
??前一个字符0次或1次扩展,最小匹配
{m,n}?扩展前一个字符m至n次(含n),最小匹配

五、selenium 模块

1、安装selenium模块

使用 pip install 命令安装selenium 模块,或者在 pycharm 里面安装,安装步骤和安装 requests 模块相同

2、安装Chromedriver

Chromedriver 是谷歌出的一款无头浏览器,我可可以用 python 中的 selenium 模块调用无头浏览器,模拟认为操作浏览器

Chromedriver的下载地址

查看你浏览器的版本,下载的无头浏览器要和你的浏览器版本相对应,打开浏览器,找到 帮助->关于 Google Chrome 查看浏览器版本,下载对应的无头浏览器

下载完成后,将无头浏览器添加到你 python 的目录中,或者在调用的时候指明无头浏览器的路径

3、selenium模块使用

Chromedriver 的设置

from selenium import webdriver

option = webdriver.ChromeOptions()
  • 设置chrome 二进制文件的位置
  • 添加启动参数(add_argument)
  • 添加扩展应用 (add_extension, add_encoded_extension)
  • 添加实验性质的设置参数 (add_experimental_option)
  • 设置调试器地址 (debugger_address)

使用

option = webdriver.ChromeOptions()
option.add_argument("--headless")  # 以无头模式运行Chrome
dr = webdriver.Chrome(options=option)

这样就会打开无头浏览器

Chromedriver浏览网页

dr.get(url)

这样就会通过url 打开网页

Chromedriver定位标签

  • find_element_by_id() #通过id查找获取
  • find_element_by_name() #通过name属性查找
  • find_element_by_class_name() #通过class属性查找
  • find_element_by_tag_name() #通过标签名字查抄
  • find_element_by_link_text() #通过浏览器中可点击的文本查找
  • find_element_by_xpath() #通过xpath表达式查找
  • find_element_by_css_selector() #通过css选择器查找
driver.find_element_by_id('01') #找到标签 ID 为 01 的标签

Chromedriver控制页面

  • 设置浏览器窗口大小:driver.set_window_size(480, 800)
  • 回退到上一个访问页面:driver.back()
  • 前进到下一个访问页面:driver.forward()
  • 退出浏览器:driver.quit()

webdriver常用操作

  • click() 点击
  • send_key(value) 输入值
  • clear() 清空输入
  • size 元素对应的大小
  • text 获取对应元素的文字
driver.find_element_by_id('01').click()
driver.find_element_by_id('02').send_key("书包")
driver.find_element_by_id('02').clear()
driver.find_element_by_id('02').size
driver.find_element_by_id('03').text

webdrive中ActionChains类的鼠标动作

  • perform():执行所有ActionChains中存储的所有行为
  • context_click():右击
  • double_click():双击
  • drag_and_drop():拖动
  • move_to_element():悬浮
  • click_and_hold():鼠标按住不松手
  • move_to_lelment():拖动到某元素
  • move_by_offset(xoffset=50,yoffset=60):按坐标移动

首先我们需要定位到响应元素, 然后使用ActionChains(实例化的浏览器)中鼠标操作(带操作的元素)的各种方法

from selenium.webdriver.common.action_chains import ActionChains
#鼠标定位到需要悬浮的元素
above=driver.find_element_by_link_text('设置')
ditu=driver.find_element_by_link_text('地图')

#对定位的元素执行鼠标操作
ActionChains(driver).move_to_element(above).perform()
ActionChains(driver).double_click(above).perform() #鼠标右击
  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值