恭喜你,当你看到这篇文章,它会是很有价值的,从最基本的知识点到项目实战,全部会展现给大家,会附上源码便于自己练习,理解。【便于练习需要,前半部分使用的是本地下载的html,需要的话,在评论区或者私信我】
另外,因篇幅长度问题,本篇只写了一个,会在另一篇全部写项目实战,感兴趣的朋友可以在看完本篇,继续看下一篇。
一、基础知识点
@注意这里有一个新手容易踩的坑:千万不要把你新创建的.py文件名称跟包是一样的,会报错。eg:bs4.py 那么这个文件在导入bs4库的时候就会发生错误
我们爬虫用的最多的是xpath,所以我们这里重点讲xpath
1.下载途径:1.在终端下载: pip install lxml
2.在settings中直接下载
2.导入库
from lxml import etree
3.打开html文件,看是否出现错误
tree = etree.HTML(open('./素材.html', 'r', encoding='UTF-8').read())
注意:
1.有一部分电脑的配置不是utf-8,所以要进行设置。
2.关于utf-8的写法: 无论是 'UTF-8' 还是 'utf-8' 甚至是 'Utf-8' 都是ok的,看自己的个人喜好
tree = etree.HTML(open('./豆瓣.html', 'r', encoding='UTF-8').read())
print(tree)
查看html能否正常打开,如果可以我们进行下一步
二、常见的使用方式
1.解析本地的文件 etree.parse()
2.解析线上的HTML字符串,etree.HTML()
是Python的ElementTree模块中的一个函数,用于将HTML内容转换为Element对象,可以用于对HTML内容进行解析和处理。其使用方法如下:
1.将HTML内容转换为Element对象:使用etree.HTML()
函数将HTML字符串转换为Element对象。
html_str = "<html><body><h1>Hello, world!</h1></body></html>"
html_element = etree.HTML(html_str)
2.处理Element对象:对转换后的Element对象进行操作或者遍历。
# 获取HTML标签
print(html_element.tag) # 输出html
# 获取body标签下的所有子标签
for child in html_element[0]:
print(child.tag) # 输出body和body下的h1标签
3.tree.xpath() 使用xpath路径查询信息,返回一个列表,当我们使用for循环遍历的时候,通常在使用tree.xpath()[0], 这样效果更好点
3.xpath的使用语法
a.路径表达式:
- ' / ' “ / ” 根的意思,表示从根节点选取 eg:tree.xpath('/html/body/li') 这里注意如果这里的语句是从( / )开始,他的意思是代表到最后一个元素的绝对位置
- ' // ' 表示直接匹配到这个位置 tree.xpath('//ul') 表示直接从html中匹配到所有的ul位置
- ' ./ ' 表示从当前节点开始匹配 tree.xpath('./li') 表示选择tree里面第一个div节点
- ' @ ' 选取属性 tree.xpath('//ul[class = " clearfix " ]') 表示直接选取到ul节点,并且选取到class = " clearfix "
路径表达式 | 结果 |
/ul/li[2] | 表示选取属于ul子元素的第二个li,[ i ]表示第i个 |
/ul/li[last()] | 表示选取属于ul子元素的最后一个li |
/ul/li[last()-3] | 表示选取属于ul子元素的倒数第三个li。理解:最后的减三,不就是倒数第三个啦 |
/ul/li[position<4] | 表示选取属于ul子元素的前三个li元素。 理解:位置小于第四个,代表的意思就是前三个 |
//a[@title = 'jj'] | 选取所有a元素,并且含有属性是title = jj的 |
* | 匹配任何元素节点 |
@* | 匹配任何属性节点 |
node() | 匹配任何类型的节点 |
1./ul/* 选取ul元素的所有子元素
2.//* 选取文档中所有的元素
3.//title[@*] 选取所有带有title元素
4. //node() 获取所有节点
需要注意的是,使用etree.HTML()
函数处理HTML字符串时,如果字符串中包含了非法字符,如未转义的字符、特殊字符等,可能会导致解析失败。此时可以使用html.escape()
函数进行转义处理,如下:
import html
html_str = "<html><body><h1>Hello, world!</h1>©</body></html>"
html_str = html.escape(html_str)
html_element = etree.HTML(html_str)
关于“ | ”的使用:
1.首先可以把它理解为{ 和 }的意思
2.“ | ”两边必须写完整的xpath路径
对比
目的(同个文档) | 查找一个标签下的不同元素 | 同时查找不同标签 |
实现路径 | //div[@id="ggg" and @class="jjj"] | //div/a | //div/c |
含义 | 查找文档中含有id="ggg"和class="jjj"元素的div标签 | 同时查找文档中div标签下的a和b |
1. 一些常用的查找方法:
- //div/a/text() : 查找div的子节点a的内容
- //div/a/@href : 查找div的子节点a中的href属性
- //div/a[@href="aaa"] :这个千万不要跟上面的弄混淆了,这个的意思是查找div的子节点a且含有href="aaa"属性。
- //* : 获取所有
- //*[@href="ggg"] : 获取所有href="ggg"的标签
- etree.tostring(x) : 将字符串x转化成二进制的字符串,通常使用后,我峨嵋你需要在下一步进行解码
x = tree.xpath('//div/a') response = etree.tostring(x, encoding = 'utf-8') # 这里decode()里面只有两种情况1.'utf-8';2. 'gbk'.默认的是'utf-8' res = response.decode('utf-8')
三、基本运用
1.我们确定要爬取的部位: 假如我们要爬取['登录', '注册', '下载豆瓣客户端'] 这几个数据
2.这个是将他们收在一起,这里我们选择爬取<body></body>里的内容
综上所述,首先进入html,然后进入body,接着进入三层div,最后进入a,代码如下
list = tree.xpath('/html/body/div/div/div/a')
print(list)
如下图就可以看到了
四、项目实战
项目一:爬取四大名著的名称和链接
"""
爬取四大名著的书名和链接
"""
# 第一步,导入我们需要用的库
import requests
from lxml import etree
# 第二步,输入网址
url = 'https://www.shicimingju.com/bookmark/sidamingzhu.html'
# 第三步,抓取解码所需的数据(对于这个数据,我等下用图片附上),对于解码我们常用的就是User-Agent 和 Cookie,还有注意 这两个之间,要加上逗号
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'
' Chrome/115.0.0.0 Safari/537.36',
'Cookie': 'Hm_lvt_649f268280b553df1f778477ee743752=1691242066;'
' Hm_lpvt_649f268280b553df1f778477ee743752=1691242201'
}
# 第四步,开始解码,这个是get请求,有时也会有post请求注意
response = requests.get(url, headers=headers)
# 第五步,解码,解析转化为字符串
html = response.content.decode('utf-8')
# 将获取到的HTML文本解析成可操作的Element对象,方便提取页面中的内容。
# Element对象:Element 对象是 lxml 库中用于表示可扩展标记语言
res = etree.HTML(html)
# 第六步,确定我们要爬取的路径,爬取路径,以及选择等下附上图片
li_list = res.xpath('//div[@class="book-item"]/h3/a')
# xpath 返回的是一个列表,我们通过for循环进行遍历出来
for li in li_list:
# 我们通常在后面加上[0],原因是这样我们得到是一个元素,而不是列表,看起来更美观
name = li.xpath('./text()')[0]
href = li.xpath('./@href')[0]
print(name, href)
接下来是xpath路径选择的全部过程,对于部分选择部分不理解的可以看上面基础点的介绍
接下来进入到我们前面数据获得的部分
好,看到这里,相信你一定有所收获了,关于项目实战,因篇幅长度问题,只写了一个,另外会单独写一篇,全是关于xpath项目实战,感兴趣的朋友可以看下一篇