xpath和bs4的使用

142 阅读3分钟

bs4的基本使用


from bs4 import BeautifulSoup
import re
soup = BeautifulSoup(html, 'html.parser')
# print(soup)
# print(type(soup))
print(soup.title)  # 完整的标签
print(soup.title.name)  # 标题

print(soup.a)  # 拿文档的第一个
print(soup.a.attrs)  # 获取标签的属性
print(soup.a.attrs['href'])  # 获取标签href的属性
print(soup.a['href'])  # 可以省略attrs
print(soup.a.get('class'))  # 获取标签class的属性
print(soup.a.get('href'))  # 获取标签href的属性
soup.a['href'] = 'https://www.baidu.com/'  # 修改
print(soup.a)  # 可以省略attrs
# string 得到标签下的文本内容 只有在此标签没有子标签     或者只有一个子标签的情况 才能返回内容否则NONe
print(soup.a.string)
print(soup.a.text)  #
print(soup.a.get_text())  # 获取标签的所有文本内容 包括子孙节点的
#  find_all查找所有
for i in soup.find_all('a'):
    print(i['id'])
    print(i.get_text())
print(soup.find_all('a', id="link3"))
print(soup.find_all('a', class_="sister1"))  # class是python的关键字
print(soup.find_all('a', class_="sister1", id="link2"))  # 组合使用
print(soup.find_all(text='story')) # text可以用string代替
print(soup.find_all(text=re.compile('.*?story.*?')))  # 只要包含了story就拿到

xpath的基本使用

from lxml import etree
tree = etree.HTML(str1)  # 将字符串解析为HTML文档 将字符串转为_Element对象
print(tree)
print(type(tree))
print(etree.tostring(tree))  # tostring_Element对象 转为字符串
# xpath 匹配所有符合条件的元素 返回的是列表 没有匹配到 也是返回空列表
# 直接写//  不管任意位置 匹配符合条件的
print(tree.xpath('//li'))  # 匹配所有的li标签
print(tree.xpath('//li/@class'))  # 匹配所有liclass属性值
print(tree.xpath('//li/@aaa'))  # 匹配所有liaaa属性值
# xpath的写法很多很多 你只要匹配的数据没问题
print(tree.xpath('//li//a'))  # 匹配所有的a标签
print(tree.xpath('//li/a'))  # 匹配所有的a标签
print(tree.xpath('//a'))  # 匹配所有的a标签

print(tree.xpath('//ul/li/a'))  # 匹配 ulli下的a标签
print(tree.xpath('//li/a[@href="link5.html"]'))  # 匹配 href="link5.html"的a标签
print(tree.xpath('//li/a[@class="test"]'))
print(tree.xpath('//span'))
print(tree.xpath('//a/span'))
print(tree.xpath('//li//span'))  # /获取子元素 多层用//

print(tree.xpath('//li/a//@class'))  # li下的a标签自己和之下所有的class属性值
print(tree.xpath('//li/a/@class'))  # li下的a标签的class属性值

print(tree.xpath('//li/a[@href="link5.html"]/text()'))  # text() 获取内容
print(tree.xpath('//li[last()]/a/@href'))  # last() 最后一个 ['link5.html']
print(tree.xpath('//li[last()-1]/a/@href'))  # last()-1 倒数第二 ['link4.html']
print(tree.xpath('//li[1]/a/@href'))  # xpath里面 索引从1开始 ['link1.html']
print(tree.xpath('(//li/a)[1]/@href'))
print(tree.xpath('//*[@class="bold"]')) # * 表示所有任意 通配符

安居客案例

''' 需求 爬取安居客的租房数据(房屋价格 位置 介绍) 1. 明确目标url cs.zu.anjuke.com/?from=HomeP… 2. 发起请求 获取响应 3. 从里面解析出租房的字段

'''


import requests
from lxml import etree

headers = {

    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'
}
response = requests.get(url='https://cs.zu.anjuke.com/?from=HomePage_TopBar', headers=headers)

# print(response.text)
tree = etree.HTML(response.text)
'''
    我们爬一页的租房字段 比如一页20条数据 
    一条数据 里有 价格 标题 地址 介绍 标签
    一条数据有几个字段  为了我们数据的对应关系(这条数据的价格对应啥标题)
    处理方法 找同级节点 这个节点包含了所有我要取字段
'''
# print(tree.xpath('//h3/a/b[@class="strongbox"]//text()')) # 标题
# print(tree.xpath('//strong[@class="price"]/text()')) # 价格

div_list = tree.xpath('//div[@class="zu-itemmod clearfix"]')  # 拿到所有的元素
# print(div_list)
for div in div_list:
    # print(div)  # 每一个元素 这个元素有我们要的租房字段
    # title = div.xpath('//div[@class="zu-info"]/h3/a/b/text()') # 把所有的标题拿到了 35个
    # // 不管任何位置 子孙节点 基于整个进行匹配 匹配所有 我们需要匹配当前div的元素
    title = div.xpath('.//div[@class="zu-info"]/h3/a/b/text()')[0] # . 当前节点开始匹配
    price = div.xpath('.//strong[@class="price"]/text()')[0]+'元/月' # . 当前节点开始匹配

    print(title,price)