python爬虫数据解析之BeautifulSoup

摘要:
Beautiful Soup是一个python库,可以从HTML或XML文件中提取数据。它可以使用您喜爱的转换器来实现文档导航、搜索和修改的常用方式。Beautiful Soup是python爬虫的三种解析方法之一。让我们从一个例子开始:froms4import Beautiful Souphtml_ doc=“”TheDormouse的故事TheDormouse's的故事紧接着有三个小姐妹;她们的名字是Elsie,Lacie和Tillie;他们住在墙的底部。…”“soup=BeautifulSoupprint这个漂亮的对象可以根据标准缩进结构输出。

BeautifulSoup是一个可以从HTML或者XML文件中提取数据的python库。它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。

BeautfulSoup是python爬虫三大解析方法之一。

首先来看个例子:

from bs4 import BeautifulSoup

html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><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"   id="link1">Elsie</a>,
<a href="http://example.com/lacie"   id="link2">Lacie</a> and
<a href="http://example.com/tillie"   id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>

<p class="story">...</p>
"""
soup = BeautifulSoup(html_doc, 'lxml')
print(soup.prettify())

 这个beautiful对象可以按照标准的缩进结构输出。

<html>
 <head>
  <title>
   The Dormouse's story
  </title>
 </head>
 <body>
  <p class="title">
   <b>
    The Dormouse's story
   </b>
  </p>
  <p class="story">
   Once upon a time there were three little sisters; and their names were
   <a class="sister" href="http://example.com/elsie" id="link1">
    Elsie
   </a>
   ,
   <a class="sister" href="http://example.com/lacie" id="link2">
    Lacie
   </a>
   and
   <a class="sister" href="http://example.com/tillie" id="link3">
    Tillie
   </a>
   ;
and they lived at the bottom of a well.
  </p>
  <p class="story">
   ...
  </p>
 </body>
</html>

接下来用以上例子来使用beautifulsoup

# soup.title 找到第一个title标签,其他也一样
print(soup.title)

 python爬虫数据解析之BeautifulSoup第1张

# soup.title.name 找到title标签的名字
print(soup.title.name)

python爬虫数据解析之BeautifulSoup第2张

# 找到第一个p标签的class属性
print(soup.p['class'])

 python爬虫数据解析之BeautifulSoup第3张

# 找到第一个p标签的属性和属性值,以字典形式呈现
print(soup.p.attrs)

 python爬虫数据解析之BeautifulSoup第4张

其属性可以修改和删除,操作方法和字典一样.

# 找到title标签的内容,3中方式
print(soup.title.string)

python爬虫数据解析之BeautifulSoup第5张

# 找到title标签的内容,并替换
soup.title.string.replace_with("No longer bold")
print(soup.title.string)

 python爬虫数据解析之BeautifulSoup第6张

# 输出head的子标签
print(soup.head.contents)

python爬虫数据解析之BeautifulSoup第7张

# 输出head的第一个子标签
print(soup.head.contents[0])

python爬虫数据解析之BeautifulSoup第8张

# 输出head的子标签
print(soup.head.children)

python爬虫数据解析之BeautifulSoup第9张

返回一个列表对象,用来做迭代.

# 输出head的所有子孙节点
print(soup.head.descendants)

 python爬虫数据解析之BeautifulSoup第10张

如果tag包含了多个子节点,tag就无法确定 .string 方法应该调用哪个子节点的内容, .string 的输出结果是 None

 如果tag中包含多个字符串  ,可以使用 .strings 来循环获取:

输出的字符串中可能包含了很多空格或空行,使用 .stripped_strings 可以去除多余空白内容:

# 找到title标签的父标签
print(soup.title.parent)

 python爬虫数据解析之BeautifulSoup第11张

# 找到第一个a标签
link = soup.a
# 找打a节点的所有父节点
for parent in link.parents:
    print(parent.name)

python爬虫数据解析之BeautifulSoup第12张

在文档树中,使用 .next_sibling 和 .previous_sibling 属性来查询兄弟节点:

find()

find(name, attrs, recursive, text, **wargs)    # recursive 递归的,循环的

# 找到第一个a节点
print(soup.find('a'))

 python爬虫数据解析之BeautifulSoup第13张

# 找文本为Elsie的第一个a节点
print(soup.find('a', text='Elsie'))

 python爬虫数据解析之BeautifulSoup第14张

# 通过正则表达式查找第一个包含字符a的标签
print(soup.find(re.compile('a')))

 python爬虫数据解析之BeautifulSoup第15张

# 找到一个包含id='link3'标签
print(soup.find(id="link3"))

python爬虫数据解析之BeautifulSoup第16张

# 找到一个包含id='link3'标签
print(soup.find(attrs={'id':'link3'}))

 python爬虫数据解析之BeautifulSoup第17张

class是python的保留关键字,所以无法使用class这个关键字。

有2种方法:

  第一种:soup.find(attrs={'class':'haha'})

  第二种:soup.find(class_='haha')

# 定义函数查找
def search_one(tag):
    return tag.has_attr('id') and tag.get('id')=='link3'
oder = soup.find(search_one)
print(oder)

 python爬虫数据解析之BeautifulSoup第18张

find_all()

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

调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=False .

# 找到所有的a标签,返回的是列表
print(soup.find_all('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>]
# 找到所有的a标签中的第一个
print(soup.find_all('a', limit=1))

python爬虫数据解析之BeautifulSoup第19张

# 找到所有包含a字符的标签,返回一个列表
print(soup.find_all(re.compile('a')))
[<head><title>The Dormouse's story</title></head>, <a   href="http://example.com/elsie" id="link1">Elsie</a>, <a   href="http://example.com/lacie" id="link2">Lacie</a>, <a   href="http://example.com/tillie" id="link3">Tillie</a>]
# 找到所有的a标签和b标签
print(soup.find_all(['a', 'b']))
[<b>The Dormouse's story</b>, <a   href="http://example.com/elsie" id="link1">Elsie</a>, <a   href="http://example.com/lacie" id="link2">Lacie</a>, <a   href="http://example.com/tillie" id="link3">Tillie</a>]
# 找到所有的有属性值为sister的a标签
print(soup.find_all("a", "sister"))
[<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>]
# 找到所有的有id属性值为link1的a标签
print(soup.find_all(id='link1'))

 python爬虫数据解析之BeautifulSoup第20张

class是python的保留关键字,所以无法使用class这个关键字。

有2种方法:

  第一种:soup.find_all(attrs={'class':'haha'})

  第二种:soup.find_all(class_='haha')

# 找到所有的内容为Elsie的内容
print(soup.find_all(text='Elsie'))
print(soup.find_all(text=['Elsie', 'Lacie']))

python爬虫数据解析之BeautifulSoup第21张

CSS选择器

Beautiful Soup支持大部分的CSS选择器 [6] ,在 Tag 或 BeautifulSoup 对象的 .select() 方法中传入字符串参数,即可使用CSS选择器的语法找到tag

常见的选择器:标签选择器(a)、类选择器(.)、id选择器(#)、层级选择器
div .dudu #lala .meme .xixi 下面好多级
div > p > a > .lala 只能是下面一级
# 找到select标签
print(soup.select('title'))

python爬虫数据解析之BeautifulSoup第22张

# 找到body下的a
print(soup.select('body 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>]

找到某个tag标签下的直接子标签

# 找到head下的title
print(soup.select('head > title'))

python爬虫数据解析之BeautifulSoup第23张

# 找到p下的a
print(soup.select('p > 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>]
# 找到p下的id选择器link1
print(soup.select('p > #link1'))

python爬虫数据解析之BeautifulSoup第24张

 找到第一个有id选择器link1第二个有类选择器sister
print(soup.select('#link1 ~ .sister'))

python爬虫数据解析之BeautifulSoup第25张

# 找到有id选择器link1和类选择器sister
print(soup.select('#link1 + .sister'))

python爬虫数据解析之BeautifulSoup第26张

# 通过类名查找
print(soup.select('.sister'))
print(soup.select("[class~=sister]"))
[<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>]
# 通过id查找
print(soup.select('a#link1'))

python爬虫数据解析之BeautifulSoup第27张

# 通过属性查找
print(soup.select('a[id]'))
[<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>]
# 通过属性查找
print(soup.select('a[href="http://example.com/elsie"]'))
# 只要包含一部分属性就行
print(soup.select('a[href*="m/el"]'))
# 属性的结尾
print(soup.select('a[href$="elsie"]'))

 python爬虫数据解析之BeautifulSoup第28张

 例子

1 爬取诗词名句网 的水浒传并保存到本地 网址:http://www.shicimingju.com/book/shuihuzhuan.html

import requests
from bs4 import BeautifulSoup
import os

#解析出所有的目录
def main(url, headers):
    response = requests.get(url=url, headers=headers).text
    soup = BeautifulSoup(response, 'lxml')
    titles = soup.find_all(attrs=['class', 'book-mulu'])
    for one_title in titles:
        # 得到一个一个a标签的列表
        mulu_lst = one_title.find_all('a')
        write_in(mulu_lst)

# 写入文件
def write_in(mulu):
    # 创建文件夹
    if not os.path.exists('shuihu'):
        os.mkdir('shuihu')
    # 解析每一章节
    for one_mulu in mulu:
        # 拿到新的页面
        text = requests.get(url='http://www.shicimingju.com'+one_mulu['href'], headers=ua_headers).text
        soup1 = BeautifulSoup(text, 'lxml')
        content = soup1.find_all(attrs=['class', 'chapter_content'])
        # 解析这个div
        for one_content in content:
            # 去出2遍空格
            con = one_content.get_text().strip()
            # 将每段空格换为换行符
            con1 = con.replace('  ', '
')
            # 以章节为名写入文件夹
            with open('shuihu/'+ one_mulu.string + '.txt', 'w', encoding='utf-8') as f:
                f.write(con1)

if __name__ == '__main__':
    url = 'http://www.shicimingju.com/book/shuihuzhuan.html'
    ua_headers = {"User-Agent":"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) "
                               "Version/5.1 Safari/534.50"}
    main(url, ua_headers)

得到本地书籍:可以拖到手机上去看

python爬虫数据解析之BeautifulSoup第29张

python爬虫数据解析之BeautifulSoup第30张

其实上段代码的beautifulsoup可以简化的,但是我为了练习find_all就写了以上代码,可以用其他方式简化的.

 2 爬取抽屉网首页的新闻标题和连接  https://dig.chouti.com/

import requests
from bs4 import BeautifulSoup

def main():
    response = requests.get(url=url, headers=ua_headers).text
    soup = BeautifulSoup(response, 'lxml')
    titles = soup.find_all('a', class_="show-content color-chag")
    for one_title in titles:
        print('标题' + one_title.text.strip() + '的链接为:' + one_title['href'])

if __name__ == '__main__':
    url = 'https://dig.chouti.com/'
    ua_headers = { "User-Agent":'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)'}
    main()

得到输出:

python爬虫数据解析之BeautifulSoup第31张

3 爬取58同城的房源信息  深圳二手房,并保存到xls文件

https://sz.58.com/ershoufang/?utm_source=market&spm=u-2d2yxv86y3v43nkddh1.BDPCPZ_BT&PGTID=0d30000c-0000-4591-0324-370565eccba8&ClickID=1

import requests
from bs4 import BeautifulSoup
import xlwt

# 得到soup对象
def main(url,headers):
    response = requests.get(url=url, headers=headers).text
    soup = BeautifulSoup(response, 'lxml')
    parse(soup)

# 解析出数据,写入xls
def parse(soup):
    # 找到带有类选择器house-list-wrap下面的所有li标签
    li_list = soup.select('ul.house-list-wrap > li')
    # 创建xls文件
    wookbook = xlwt.Workbook(encoding='utf-8')
    sheet = wookbook.add_sheet('58 sheet')
    title_lst = ['name', 'total_price', 'one_price', 'huxing', 'area', 'direction', 'height']
    hang, lie = 0, 0
    # 把第零行的标题写进去
    for one in title_lst:
        sheet.write(0, lie, one)
        lie += 1
    # 写入每一行
    hang += 1
    for one_li in li_list:
        sheet.write(hang, 0, one_li.select('h2 > a')[0].text.strip())
        sheet.write(hang, 1, one_li.select('div.price > p.sum')[0].text)
        sheet.write(hang, 2, one_li.select('div.price > p.unit')[0].text)
        sheet.write(hang, 3, one_li.select('div.list-info > p.baseinfo > span')[0].text)
        sheet.write(hang, 4, one_li.select('div.list-info > p.baseinfo > span')[1].text.strip())
        sheet.write(hang, 5, one_li.select('div.list-info > p.baseinfo > span')[2].text)
        sheet.write(hang, 6, one_li.select('div.list-info > p.baseinfo > span')[3].text)
        hang += 1
    wookbook.save('58深圳二手房子.xls')


if __name__ == '__main__':
    url = 'https://sz.58.com/ershoufang/?utm_source=market&spm=u-2d2yxv86y3v43nkddh1.' 
          'BDPCPZ_BT&PGTID=0d30000c-0000-4591-0324-370565eccba8&ClickID=1'
    ua_headers = {"User-Agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, "
                                "like Gecko) Version/5.1 Safari/534.50"}
    main(url, ua_headers)

得到xls文件.

python爬虫数据解析之BeautifulSoup第32张

免责声明:文章转载自《python爬虫数据解析之BeautifulSoup》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇WebSocket 实现长连接演示代码phpstudy 升级(更换) mysql 版本下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

pip命令及虚拟环境的建立

pip命令及虚拟环境的建立  以下命令是pip命令,是帮助我们安装解决python所需要的环境包 列出已经安装的包 pip list 安装要安装的包 pip install 包名 安装特定版本 pip install django==1.1.5 #=在python中代表赋值的作用,只有==才是等于的意思 导出python环境 pip freeze &...

python获取教务管理系统的MM照片

前提:你的教务管理系统是明文存储大家的图片,加密的图片就不好弄了... 也就是能够通过浏览器直接访问...技术上就不存在什么问题了...如果是学号存储的就更方便了 然后我们就可以写个小脚本了...其实就是直接url获取然后保存在本地... 第一个python小脚本...练手玩一玩... 如果要效率高可以用多线程... 大家就可以愉快的找到MM的照片啦!...

(2019版本可用)Pycharm的安装,破解

前言 python的操作工具pycharm,是专门用来写python语言的。 因为之前在网上找到了,但是太麻烦了,所以整理整理。 pycharm安装 官网可以选择下载(pycharm最新版有可能破解不了): http://www.jetbrains.com/pycharm/download/#section=windows 博主我提供的(我的版本支持这个破...

python基础入门之八 —— 公共操作

1、运算符 运算符 功能 是否支持 字符串 列表 元组 字典 集合 + 合并 √ √ √     * 复制 √ √ √     in 判断是否存在 √ √ √ √ √ not in 判断是否不存在 √ √ √ √ √ 2、公共方法 len() 统计容器中元素的个数 del/del() 删除 max() 返回容器中元素...

Python 的音乐库

前言 其实处理这个用 Matlab 最方便,之前把 guitar-synthesizer 从 Matlab 移植到 Python,过程中更是体会到了这一点。不过 Matlab 安装包又大,启动又慢,还是收费软件。。平常也不怎么用得到,毕竟我也不搞算法、仿真。 所以还是,Python 真香hhh 库 音乐的时域处理 标准库有个 wave 模块,可以转成 w...

Python操作远程机器

操作远程机器主要使用的有paramiko,WMI(Windows Management Instrumentation),SMBConnection. paramiko paramiko使用SSH2协议操作远程机器,是Python语言写的一个模块。 安装 pip install paramiko 使用 使用主要包括执行命令,上传文件和下载文件。 连接...