python--爬虫(XPath与BeautifulSoup4)

获取页面内容除使用正则意外,还可以使用XPath,其原理是将html代码转换为xml格式,然后使用XPath查找html节点或元素。

选取节点

XPath使用路径表达式来选取XML文档中的节点或节点集。
常用的路径表达式见下表:

表达式描述
nodename选取此节点的所有子节点
/从根节点选取
//从匹配选择的当前节点选择文档中的节点,不考虑其是否为子级
.选取当前节点
..选取当前节点的父节点
@选取属性

谓语

谓语用来查找某个特定的节点或者包含某个指定的值得节点,被嵌在方括号中。

路径表达式释义
/one/two[1]选取属于one子元素的第一个two元素
/one/two[last()]选取属于one子元素的最后一个two元素
/one/two[last()-1]选取属于one子元素的倒数第二个two元素
/one/two[position()<3]选取最前面的两个属于one元素的子元素two元素
//one[@lang]选取所有拥有名为lang的属性的one元素
//one[@lang='test']选取所有拥有值为test的lang属性的one元素
/one/two[position>10]选取one元素的所有two元素,且其中position属性的值大于10

选取未知节点

通配符描述
*匹配如何元素节点
@*匹配任何属性节点
node()匹配任何类型节点

例:

路径表达式结果
/one/*选取one中所有的子元素
//*选取文档中的所有元素
//one[@*]选取所有带有属性的one元素

选取若干路径

可以使用管道符“|”选取若干个路径,相当于或

XPath运算符

运算符描述
+加法
-减法
*乘法
div除法
=等于
!=不等于
<小于
<=小于或等于
>大于
>=大于或等于
or
and
mod计算余数

XPath的使用

from lxml.html import etree

# 获取到的要匹配的html字符串
html = ''
content = etree.HTML(html)
# 返回所有匹配成功的列表集合
res = content.xpath('表达式')

BeautifulSoup4的使用

和 lxml 一样,Beautiful Soup 也是一个HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML 数据。
想使用BeautifulSoup4首先需要安装,执行pip install beautifulsoup4安装,BeautifulSoup4的使用方法如下

from bs4 import BeautifulSoup

html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
soup = BeautifulSoup(html, 'lxml')
# 打开本地Html文件创建对象
# soup = BeautifulSoup(open('xxx.html'))

print(soup.prettify())

# 获取标签
soup.title    # 获取title
soup.p    # 获取p标签
soup.a    #  获取a标签

print(soup.name)
# [document] #soup 对象本身比较特殊,它的 name 即为 [document]

print(soup.head.name)
# head #对于其他内部标签,输出的值便为标签本身的名称

print(soup.p.attrs)
# {'class': ['title'], 'name': 'dromouse'}
# 在这里,我们把 p 标签的所有属性打印输出了出来,得到的类型是一个字典。

print(soup.p['class']) # soup.p.get('class')
# ['title'] #还可以利用get方法,传入属性的名称,二者是等价的

soup(p['class']) = "newClass"
print(soup.p) # 可以对这些属性和内容等等进行修改
# <p class="newClass" name="dromouse"><b>The Dormouse's story</b></p>

del(soup.p['class']) # 还可以对这个属性进行删除
print (soup.p)
# <p name="dromouse"><b>The Dormouse's story</b></p>

# 获取标签内文字
print(soup.p.string)

# tag 的 .content 属性可以将tag的子节点以列表的方式输出
print(soup.head.contents)    # [<title>The Dormouse's story</title>]

# .children它返回的不是一个 list(是一个列表生成器),不过我们可以通过遍历获取所有子节点。
print(soup.head.children)    # <list_iterator object at 0x000002B9D7E4CFD0>

# .descendants 获取所有子孙节点
print(soup.descendants)    # 结果是一个生成器 <generator object Tag.descendants at 0x0000020AAC5B1B10>

BeautifulSoup4的搜索

# 使用find_all(name, attrs, recursive, text, **kwargs)查找

# 传入name参数
soup.find_all('p')    # 查找所有p标签
soup.find_all('a')    # 查找所有a标签
soup.find_all(re.compile('^p'))    # 使用正则查找所有以p打头的标签
soup.find_all(['p', 'a'])    # 传入列表,查找所有p和a标签

# 传入attrs参数
soup.find_all(id='link1')    # 查找所有id未link1的标签,通过标签属性查找的方式适用大多数标签属性,包括id,style,title,但有 “-”,Class标签属性例外。
soup.find_all(attrs={'class': 'sister'})

# 传入text参数
soup.find_all(text="Lacie")    # 产找所有含有内容为Lacie的对象
soup.find_all(text=['aaa', 'bbb'])
soup.find_all(text=re.compile("Tit"))    # 传入正则匹配

# css选择查找
soup.select('title')    # 根据标签查找
soup.select('#link1')    # 根据Id查找
soup.select('.sister')    # 根据类名查找
soup.select('p #link1')    # 组合查找
soup.select("head > title")    # 查找子标签
soup.select('a[class="sister"]')    # 属性查找
soup.select('title')[0].get_text()    # 使用get_text获取内容

实例

from bs4 import BeautifulSoup
from urllib.request import *
import json

def tencent():
    url = 'https://hr.tencent.com'
    header = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36"}
    request = Request(url + '/position.php?&start=0#a', headers=header)
    response = urlopen(request)
    html = response.read()
    # with open('html.txt', 'wb+') as f:
    #     f.write(html)

    soup = BeautifulSoup(html, 'lxml')
    result = soup.select('tr[class="even"]')
    result2 = soup.select('tr[class="old"]')
    result.extend(result2)
    items = []
    for site in result:
        item = {}
        item['name'] = site.select('td a')[0].get_text()
        item['link'] = site.select('td a')[0].attrs['href']
        item['category'] = site.select('td')[1].get_text()
        item['recruitNumber'] = site.select('td')[2].get_text()
        item['workLocation'] = site.select('td')[3].get_text()
        item['publishTime'] = site.select('td')[4].get_text()

        items.append(item)

    line = json.dumps(items, ensure_ascii=False)
    with open('html.txt', 'w') as f:
        f.write(line)

if __name__ == "__main__":
    tencent()

转载于:https://www.cnblogs.com/peilanluo/p/10311827.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值