抓取工具 | 速度 | 使用难度 | 安装 |
---|---|---|---|
正则re | 最快 | 一般 | 内置 |
xpath | 快 | 简单 | 简单 |
bs4 | 慢 | 最简单 | 简单 |
注:xpath 一般与lxml 一起使用
简单来说:
正则re 是通过html str进行匹配的
xpath 是通过html节点 进行匹配
bs4 则通过css的选择器进行匹配
re的方法
pattern = re.compile('^\d+$')
str = 'abc123'
# 表示重头匹配 result有可能报错
result = pattern.match(str)
# 表示任意位置匹配
result = pattern.match(str)
# 爬虫最常用的的findall
result = pattern.findall(str)
# sub 替换
one = 'chuan_zhi_hei_ma'
sub_pattern = re.compile('_')
result = sub_pattern.sub('', one)
# 调换顺序
two = "hello world,fsd,;fds;gds,A B"
sub_pattern = re.compile('(\w+) (\w+)')
result = sub_pattern.sub(r'\2 \1', two)
# split 分割
thre = "a,b,,,,c;;;d ,f e"
split_pattern = re.compile('[,; ]+')
result = split_pattern.split(thre)
# 汉字--unicode字符 [u4e00-u9fa5]
china_str = "小明老王是一家人is not"
china_pattern = re.compile('[\u4e00-\u9fa5]+')
china_pattern = re.compile('[^\u4e00-\u9fa5]+')
result = china_pattern.findall(china_str)
re 正则findall中的参数
# 1. . 点 匹配任意字符 除了\n ; 但是在DOTALL 可以匹配
one = """
assffddsfb
MMMMMMMMMM
NNNNNNNNNB
"""
# 1. 正则表达式
pattern = re.compile('a(.*)b')
# 可以匹配的\n 12行13行等价
pattern = re.compile('a(.*)b', re.DOTALL)
pattern = re.compile('a(.*)b', re.S)
# 可以匹配 不区分大小写
pattern = re.compile('a(.*)b', re.S | re.IGNORECASE)
pattern = re.compile('a(.*)b', re.S | re.I)
# 2. 调用findall---list
result = pattern.findall(one)
注:在python3中 匹配\w 会匹配到中文字符
所以经常使用的
pattern = re.compile(r’[1-9a-zA-Z_]’)
发现结果是一个element对象,这个对象能够继续使用xpath方法:要注意的是 xpath的语法就变成了在此element的路径进行下一步的匹配 使用 ./ (点斜杠) 表示当前路径
下面是:xpath的语法
xpath的概述XPath (XML Path Language),解析查找提取信息的语言
xml是和服务器交互的数据格式和json的作用一致
html是浏览器解析标签数据显示给用户
xpath的节点关系:根节点,子节点,父节点,兄弟节点,子节点,后代节点
xpath的重点语法获取任意节点://
xpath的重点语法根据属性获取节点:标签[@属性 = ‘值’]
xpath的获取节点属性值:@属性值
xpath的获取节点文本值:text()
xpath的使用方法: 如果没有取到想要的结果,再去看他的父元素,一直往上找。
#创建 Beautiful Soup 对象
# soup = BeautifulSoup(html)
#打开本地 HTML 文件的方式来创建对象
#soup = BeautifulSoup(open('index.html'))
soup = BeautifulSoup(html_str, 'lxml') # 常用的方式
#格式化输出 soup 对象的内容
result = soup.prettify()
常用的方法如下
2.1
find_all(name, attrs, recursive, text, **kwargs)
2.3 CSS选择器
(1)通过标签选择器查找
print soup.select('title')
#[The Dormouse's story ]
(2)通过类选择器查找
print soup.select('.sister')
#[, Lacie, Tillie]
(3)通过 id 选择器查找
print soup.select('#link1')
#[]
(4)层级选择器 查找
print soup.select('p #link1')
#[]
(5)通过属性选择器查找
print soup.select('a[href="http://example.com/elsie"]')
#[]
(6) 获取文本内容 get_text()
soup = BeautifulSoup(html, 'lxml')
print type(soup.select('title'))
print soup.select('title')[0].get_text()
for title in soup.select('title'):
print title.get_text()
(7) 获取属性 get('属性的名字')
soup = BeautifulSoup(html, 'lxml')
print type(soup.select('a'))
print soup.select('a')[0].get('href')
举例如下
# pip install beautifulsoup4
from bs4 import BeautifulSoup
import re
if __name__ == '__main__':
html_str = """
The Dormouse's story
The Dormouse's story
Once upon a time there were three little sisters; and their names were
,
Lacie and
Tillie;
and they lived at the bottom of a well.
...
"""
# 1. 转类型
soup = BeautifulSoup(html_str, 'lxml')
# 2.3 select 选择器--list
# 标签选择器
# 类选择器
# ID选择器
# 层级选择器 后代选择器
# 组选择器
# 属性选择器
result = soup.select('a')
result = soup.select('.sister')
result = soup.select('head title')
result = soup.select('#link3,#link1')
result = soup.select('p[name="dromouse"]')
result = soup.select('#link3')
# 标签包裹的内容
# result = result[0].get_text()
# 标签的属性
result = result[0].get('href')
print(result)
# 2.解析数据
# 2.1 find--获取符合条件 第一个
result = soup.find()
result = soup.find(attrs={
"id": "link2"
})
pattern = re.compile('^b')
result = soup.find(pattern)
result = soup.find(text="...")
# 2.2 find_all ---list
result = soup.find_all('a')