python爬虫2——beautifusoap4的使用讲解与腾讯招聘网站爬虫

本文深入解析BeautifulSoup4库的使用方法,涵盖HTML解析、文档树遍历、搜索及CSS选择器技巧,并通过腾讯招聘网站爬虫实例展示数据抓取流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、CSS 选择器:BeautifulSoup4

首先和 lxml 一样,Beautiful Soup 也是一个HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML 数据。

lxml 只会局部遍历,而Beautiful Soup 是基于HTML DOM的,会载入整个文档,解析整个DOM树,因此时间和内存开销都会大很多,所以性能要低于lxml。

BeautifulSoup 用来解析 HTML 比较简单,API非常人性化,支持CSS选择器、Python标准库中的HTML解析器,也支持 lxml 的 XML解析器。

Beautiful Soup 3 目前已经停止开发,推荐现在的项目使用Beautiful Soup 4。使用 pip 安装即可:pip install beautifulsoup4

官方文档:http://beautifulsoup.readthedocs.io/zh_CN/v4.4.0

说到解析html的工具,主要有三个、BeautifulSoup、lxml:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

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>
"""

#创建 Beautiful Soup 对象
soup = BeautifulSoup(html,'html.parser', from_encoding='utf-8')

#打开本地 HTML 文件的方式来创建对象
#soup = BeautifulSoup(open('index.html'))

#格式化输出 soup 对象的内容
print soup.prettify()

soup.prettify()能够整理html的格式变得更为整洁;下面这句指定了html 的parser

soup = BeautifulSoup(html,'html.parser', from_encoding='utf-8')

也可以通过soup = BeautifulSoup(html,“lxml”)  指定解析器

二、四大对象种类

Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:

1,Tag

2,NavigableString

3,BeautifulSoup

4,Comment

1,Tag

Tag就是html中的标签,例如:

<p class="title" name="dromouse">
   <b>
    The Dormouse's story
   </b>
  </p>

这些p、b都是标签

将原来的代码进行修改,看如何找到这些标签:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

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>
"""

#创建 Beautiful Soup 对象
soup = BeautifulSoup(html,'html.parser', from_encoding='utf-8')
# 获取title
print soup.title
# 获取header
print soup.head
# 获取a标签,只取了第一个
print soup.a
# p也是只取了第一个
print soup.p
# 打印soup.a的类型
print type(soup.a)

#打开本地 HTML 文件的方式来创建对象
#soup = BeautifulSoup(open('index.html'))

#格式化输出 soup 对象的内容
# print soup.prettify()

对于tag而言,有两个属性很重要,一个是name,另一个是attrs

操作name、attrs和class的方法如下:

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

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

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

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

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

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

2,NavigableString

有了标签之后,要怎么取出标签内部的文字?用.string 就可以了!

print soup.p.string
# <class 'bs4.element.NavigableString'>
print type(soup.p.string)

3, BeautifulSoup

BeautifulSoup 对象表示的是一个文档的内容。大部分时候,可以把它当作 Tag 对象,是一个特殊的 Tag,我们可以分别获取它的类型,名称,以及属性来感受一下

#<type 'unicode'>
print type(soup.name)

# [document]
print soup.name

# {}
print soup.attrs # 文档本身的属性为空

4,Comment

获取注释内的内容,比如<!-- aa --> 会获取aa:

print soup.a.string
print type(soup.a.string)

输出:

 Elsie
<class 'bs4.element.Comment'>

三、遍历文档树

1. 直接子节点 :.contents .children 属性

content:

标签的contents属性可以将子节点的内容以列表方式展示

print soup.head.contents

输出:[<title>The Dormouse's story</title>]

print soup.head.contents[0]

输出:<title>The Dormouse's story</title>

children:

这个返回的不是一个列表

print type(soup.body.children)

<type 'listiterator'>

它是一个迭代类型的

下面这种方式即可打印出全部body的子节点:

for child in soup.body.children:
    print child

2. 所有子孙节点: .descendants 属性

与.contents、children不同,.descendants 不仅包括直接子节点,包括所有子孙节点,遍历的方式如下:

for child in soup.html.descendants:
    print child

可以打印出所有节点。

3. 节点内容: .string 属性

如果一个标签里面没有标签了,那么 .string 就会返回标签里面的内容。如果标签里面只有唯一的一个标签了,那么 .string 也会返回最里面的内容。其他使用方式是一样的。

四、搜索文档树

1,find_all(name, attrs, recursive, text, **kwargs)

参数说明:

(1)name

name 参数可以查找所有名字为 name 的tag,字符串对象会被自动忽略掉;

A.传字符串

查找文档中所有的<b>标签:

print soup.findAll('a')

结果:[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
返回的事一个列表

B.传正则表达式

查出所有以t开头的标签:

print soup.findAll(re.compile("^t"))

C.传列表

查所有title和b的标签:

print soup.findAll(['title','b'])

(2)keyword 参数

print soup.find_all(id='link2')

(3)text 参数

text就是根据文本内容来查找的,可以传 字符串、正则表达式、列表

print soup.find_all(text="The Dormouse's story")

输出:[u"The Dormouse's story", u"The Dormouse's story"]

五、CSS选择器

写 CSS 时,标签名不加任何修饰,类名前加.,id名前加#

可以通过css选择器来进行选择,用到的方法是 soup.select(),返回类型是 list

1,通过标签名查找

print soup.select('title')

2,通过类名查找

print soup.select('.sister')

3,通过 id 名查找

print soup.select('#link1')

4,组合查找

print soup.select('p #link1')

和css选择器是一样的

直接子标签查找,则使用 > 分隔

print soup.select("head > title")

5,属性查找

print soup.select('a[class="sister"]')

6,获取内容

for title in soup.select('title'):
    print title.get_text()

7,获取属性

node.select('td a')[0].attrs['href']

六、腾讯招聘网站爬虫

腾讯招聘:https://hr.tencent.com/

1,分析网页

页码的规律:

https://hr.tencent.com/position.php?&start=0#a

https://hr.tencent.com/position.php?&start=10#a

https://hr.tencent.com/position.php?&start=20#a

因此,第几页相当于  start=(页数-1)*10

我感兴趣的数据是职位信息:

分析一下每一行的格式,发现class为even或odd:

2,获取一个页面的全部职位信息

from bs4 import BeautifulSoup
import urllib2
import urllib
import json    # 使用了json格式存储

url = 'https://hr.tencent.com/position.php?&start=0#a'
request = urllib2.Request(url)
response =urllib2.urlopen(request)
resHtml = response.read()

soup = BeautifulSoup(resHtml,'html.parser', from_encoding='utf-8')
result = soup.select(".even")
result += soup.select(".odd")
print len(result)

for node in result:
    print node

发现这样是可以找到所有的职位信息

3,整理node的内容为json格式并输出

# 以json格式输出到文件中
# 禁用ascii编码,按utf-8编码
line = json.dumps(items, ensure_ascii=False)
output =open('tencent.json','w')
output.write(line.encode('utf-8'))
output.close()

这样就可以整理出一个json文件了!

文件内容:

[{"ztime": "2018-10-16", "zname": "21228-MMORPG游戏本地化策划(深圳) ", "detailLink": "position_detail.php?id=44814&keywords=&tid=0&lid=0", "zlocal": "深圳", "znum": "1", "ztype": "产品/项目类"}, {"ztime": "2018-10-16", "zname": "SA-腾讯社交广告平台产品运营经理(生态平台业务)(上海) ", "detailLink": "position_detail.php?id=44816&keywords=&tid=0&lid=0", "zlocal": "上海", "znum": "1", "ztype": "产品/项目类"}, {"ztime": "2018-10-16", "zname": "PCG04-工业设计师", "detailLink": "position_detail.php?id=44819&keywords=&tid=0&lid=0", "zlocal": "深圳", "znum": "1", "ztype": "设计类"}, {"ztime": "2018-10-16", "zname": "22090-天天快报-数据开发工程师(北京)", "detailLink": "position_detail.php?id=44810&keywords=&tid=0&lid=0", "zlocal": "北京", "znum": "3", "ztype": "技术类"}, {"ztime": "2018-10-16", "zname": "23673-娱乐热点运营编辑(北京)", "detailLink": "position_detail.php?id=44812&keywords=&tid=0&lid=0", "zlocal": "北京", "znum": "1", "ztype": "内容编辑类"}, {"ztime": "2018-10-16", "zname": "21228-游戏产品运营活动策划(深圳)", "detailLink": "position_detail.php?id=44815&keywords=&tid=0&lid=0", "zlocal": "深圳", "znum": "1", "ztype": "产品/项目类"}, {"ztime": "2018-10-16", "zname": "15573-手游系统与关卡策划(深圳)", "detailLink": "position_detail.php?id=44818&keywords=&tid=0&lid=0", "zlocal": "深圳", "znum": "2", "ztype": "产品/项目类"}, {"ztime": "2018-10-16", "zname": "PCG01-QQ大数据应用专家 ", "detailLink": "position_detail.php?id=44808&keywords=&tid=0&lid=0", "zlocal": "深圳", "znum": "1", "ztype": "技术类"}, {"ztime": "2018-10-16", "zname": "22834-腾讯音乐战略发展副总监(深圳)", "detailLink": "position_detail.php?id=44811&keywords=&tid=0&lid=0", "zlocal": "深圳", "znum": "1", "ztype": "市场类"}, {"ztime": "2018-10-16", "zname": "21228-集换式卡牌游戏本地化策划(深圳) ", "detailLink": "position_detail.php?id=44813&keywords=&tid=0&lid=0", "zlocal": "深圳", "znum": "1", "ztype": "产品/项目类"}]

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值