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')) # 匹配所有li的class属性值
print(tree.xpath('//li/@aaa')) # 匹配所有li的aaa属性值
# xpath的写法很多很多 你只要匹配的数据没问题
print(tree.xpath('//li//a')) # 匹配所有的a标签
print(tree.xpath('//li/a')) # 匹配所有的a标签
print(tree.xpath('//a')) # 匹配所有的a标签
print(tree.xpath('//ul/li/a')) # 匹配 ul下li下的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)