数据匹配的三中方法,bs4,xpath,正则
第一种:正则(先导入re库)
分为三种查找方法式:re.math(),re.search(),re.findall()
re.math():是从所要匹配的字符串的起始位置开始匹配且只值输出一个值,一般不用因为太耗时了;
re.search():从所要匹配的字符串的任意位置匹配,但是只输入第一找到的匹配值,所以不适合大多时候;
re,findall():从所要匹配的字符串的任意位置匹配,并输入所有的匹配的值【所以这个匹配方法用的在最多】
匹配的格式:
re.math(patterm,string,flag)
re.search(patterm,string,flag)
re.findall(patterm,string,flag) 【findall输出多个值,且多个值存放在一个列表中】
括号中的三个参数:
patterm代表匹配用的正则
string代表所要匹配的字符串
flag代表匹配的标记【可以不写】
常用的标记
re.M :多行匹配时,会使得^ $能一行一行的匹配【不加时整个字符串当成一行】
re.S :使得.能匹配任何包括换行符在内的任意字符
re.I :使得匹配是正则对大小不敏感
正则表达式所用的元字符
. 【点】代表可以匹配任意一个字符,除了换行符意外
^在中括号里便是逻辑非 例:[^1234]
\d :表示匹配任意一个数字与[0-9]效果相同
\D :表示匹配非数字的任意字符与[^0-9]效果相同
\w :表示匹配任意一个字母,数字或者下划线的字符 与[a-zA-Z0-1_]效果相同
\W :表示 匹配任意一个非字母,数字或者下划线的字符 与[^a-zA-Z0-9_]效果相同
\s :表示匹配任意一个换行符,换页符,空格,制表符,回车符, 与[\n\f \t\r]效果相同
\S :表示匹配任意一个非换行符,换页符,空格,制表符,回车符 与[^\n\f \t\r]效果相同
\b :用来匹配单词的结尾
\B :用来匹配单词含有某些字符且不易该字符结尾
正则表达式的边界字符
^ :表示匹配字符串的开始
$ :表示匹配字符串的结束
\A :表示匹配字符串的开始
\Z :表示匹配字符串的结束
^,$ 如果字符串有多行且在re.M标记下,^,$会将每一行当作一个字符串
\A \Z在re.M标记下不会影响多行匹配
第二种 xpath
# 导入xpath相关的库 from lxml import etree # 通过etree将html读取并创建出一颗树 html_tree = etree.parse("test.html") # print(html_tree) # 获取所有的li节点 ret = html_tree.xpath("//li") # 获取所有的li节点的内容 ret = html_tree.xpath("//li/text()") # 获取所有的li的class属性的值 ret = html_tree.xpath("//li/@class") # 获取所有的class值为nene的li ret = html_tree.xpath("//li[@class='nene']/text()") # 1、层级定位 ret = html_tree.xpath("/html//div/ol") # ret = html_tree.xpath("//ol") # 【注意】"/"代表当前节点的直接子节点,"//"当前节点的后代节点 # 2、属性定位 ret = html_tree.xpath("//div//li[@class='dudu']") # 【模糊匹配】 # 定位所有class值以"h"开头的li ret = html_tree.xpath("//li[starts-with(@class,'h')]") # 包含contains()、以xx结尾ends-with() # 【逻辑运算】 ret = html_tree.xpath("//li[@class='hehe' and @id='tata']") #逻辑且 ret = html_tree.xpath("//li[@class='hehe' or @class='xixi']") #逻辑或 # ret = html_tree.xpath("//li[not @class='hehe']") #不存在逻辑非 # 3、读取文本 ret = html_tree.xpath("//a/text()") # 【注意】只能读取纯文本,不能读取标签 #4、读取属性 ret = html_tree.xpath("//a/@href") # 【注意】某一个节点对象也可以使用xpath语法去定位(因为节点的结构都是xml) obj = html_tree.xpath("//div[@class='hh']")[0] print(obj) ret = obj.xpath("//a") print(ret)
第三种 bs4
# 引入BeautifulSoup from bs4 import BeautifulSoup fp = open("soup_test.html","r",encoding='utf-8') # print(fp.read()) # 基于被打开的html文件创建一个BeautifulSoup对象 soup = BeautifulSoup(fp,'lxml') # lxml是解析器,如果bs4对象采用这个解析器,可以大大的增加其效率 # print(soup) # 1、根据标签名查找对象 (此时只能从众多的标签中取首个) # print(soup.title) # print(soup.li) # 2、获取节点的属性值 aobj = soup.a # print(aobj["title"]) # print(aobj["href"]) # print(aobj.attrs) # 3、获取节点的内容 l = soup.li # print(l.string) # print(l.get_text()) # 【注意】.string获取的是标签里面的字符串(包括注释的内容),get_text()方法获取到的是标签里面的字符串(不包括注释),当既有注释又有字符串是用get_text() # 4、获取子节点 # 1)获取直接的子节点 #print(soup.body.contents) # 返回的是一个列表,包含子节点和换行 # print(soup.body.children) # 返回一个迭代器 # for hehe in soup.body.children: # print(hehe) # 2)获取所有的子节点 # print(soup.body.descendants) # 返回一个迭代器,里面递归存储了所有后代 # for h in soup.body.descendants: # print(h) # 5、根据相关的方法来查找对象 # 1)find()方法,返回的是首个对象 # print(soup.find("a")) # print(soup.find("a",id="hong")) # 寻找所有的id值为“hong”的a标签中首个 # print(soup.find("a",class_ = "taohua")) # 2)find_all() 查找所有的对象,返回的是一个列表 # print(soup.find_all("a")) # print(soup.find_all(["a","span"])) # # print(soup.find_all("a",name="he")) # bs4是不能用name来做属性限制的 # print(soup.find_all("a",id="hong")) # 3)select()方法,通过css选择器来选择,返回的是一个列表 # print(soup.select("#meng")) print(soup.select("[name=he]")[0].string) # print(soup.select(".cao")) # print(soup.select("div .tang"))