beautifulsoup 解析网页

beautifulsoup 解析网页

 前一篇文章讲解了一点用re提取信息的方法,但是这种方法很麻烦,需要去仔细核对多个链接才能总结出规律,而且规律普适性不强,有兴趣的可以参考如下链接:
re模块复习
 这里再讲一种特殊的方法,采用Beautiful 模块直接解析网页来获取想要的数据。

  什么是Beautiful Soup?接着往下看。

一、介绍

  Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间。以下全部使用 Beautiful Soup 4版本。

  更多介绍参考其说明文档:https://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/

二、安装调用

  安装很简单,直接pip

pip install beautifulsoup4

  它的调用很奇怪,因为它封装在bs4中,所以调用如下:

from bs4 import BeautifulSoup

  说白了,Beautiful Soup就是通过某种解析方式,把原始的html代码美化成易读的格式,然后才通过其select方法或者直接定位来抽取需要的数据。

  1. 其基本语法:
# soup就是美化完的代码
soup = BeautifulSoup(res.text,features="lxml")
soup

 原始的res.text是这样的
在这里插入图片描述
 美化后的是这样的,完全和网页的样式一致:
在这里插入图片描述

  2. 参数详解:

 常用的参数就两个
 markup:需要解析的对象
 features:指定具体的解析方式,如果不指定,Beautiful Soup选择最合适的解析器来解析这段文档。

 就目前,Beautiful Soup支持如下几种解析方式

解析器使用方法优势劣势
Python标准库BeautifulSoup(markup, “html.parser”)内置,速度中等,容错里强之前的版本不好
lxml HTML 解析器BeautifulSoup(markup, “lxml”)速度快,容错里强需要安装C语言库
lxml XML 解析器BeautifulSoup(markup, “xml”)速度快,唯一支持XML的解析器需要安装C语言库
html5libBeautifulSoup(markup, “html5lib”)最好的容错性,以浏览器的方式解析文档速度慢

 推荐使用lxml作为解析器,因为效率更高。但其他的也可以解析,只是解析的呈现效果有些许差异。

三、 定位、提取数据:

  说到定位和提取,就不得不说说HTML的结构了。首先看一个网页的结构

在这里插入图片描述

 3.1 结构释义

基本标签

  • <html></html>称为根元素,所有的网页元素都在<html></html>中

  • <head></head>元素用于定义文档的头部,定义字体、美化样式、标题等等

  • 头部元素含有有:<meta> <title> <link> <script> <style>
      <title> 标签定义文档的标题
      <meta> 标签提供关于 HTML 文档的元数据。元数据不会显示在页面上,meta 元素被用于规定页面的描述、关键词、文档的作者、最后修改时间等。
      <link> 元素引入外部样式
      <script> 元素该元素可以定义页面的脚本内容
      <style> 标签用于为 HTML 文档定义样式信息

  • <body></body> 元素用于定义网页显示的内容,这个是主要显示东西,我们需要的信息也会在这里面。
      <div> 它可用于文档布局、组合其他HTML元素的容器。
     <hx> HTML 标题,有六种分别是h1 h2 h3 h4 h5 h6,h1顶级标题,h6末级标题
     <p> 定义段落,会自动在其前后创建一些空白。不一定必须是分段,可以只加空格
     <br> 会在浏览器插入一个简单的换行符。
     <hr> 定义 HTML 页面中的主题变化(比如话题的转移),并显示为一条水平线。
     <a> 用来设置超文本链接。点击超链接可以实现跳转。
          href属性:描述了链接的目标URL。
          target属性:设置链接跳转方式。
     <img> 用来申明图像的插入。
          src属性:规定显示图像的 URL。URL为图片的相对路径或者绝对路径均可。
          alt属性:规定图像的替代文本。
          title属性:定义图片的标题,鼠标移动到图片出现。
     <span> 用来组合文档中的行内元素,可用作文本的容器。 span 元素没有固定的格式表现,当对它应用样式时,它才会产生视觉上的变化。
     <ul> ul 标签作为无序列表,它是一个项目的列表。
     <li> 每个列表项始于 <li> 标签
    这个地方说不清楚了,直接上图
    在这里插入图片描述
     <ol> 有序列表也是一列项目,列表项目使用数字进行标记。 有序列表始于 <ol> 标签。每个列表项始于 <li> 标签
    在这里插入图片描述
     <!–注释说明–> 用于在源代码中插入注释。注释不会显示在浏览器中。 可使用注释对代码进行解释,这样做有助于在以后的时间对代码的修改,当编写了大量代码时尤其有用

文本格式化标签

  • <b> 以粗体字体形式展现内容
  • <strong> strong标签与b标签都表示粗体。 但strong表示强调
  • <i> 以斜体字体形式展现内容
  • <pre> pre 标签可定义预格式化的文本。 被包围在 pre 标签 元素中的文本通常会保留空格和换行符。而文本也会呈现为等宽字体
  • <bdo> 指定文本方向,其dir属性申明文本显示方向
  • <sub> 定义下标文本。下标文本将会显示在当前文本流中字符高度的一半为基准线的下方
  • <sup> 定义上标文本。上标文本将会显示在当前文本流中字符高度的一半为基准线的上方

标签属性
 HTML 元素可以通过设置属性,实现某些特定的效果。属性一般描述于开始标签。属性总是以名称/值对的形式出现,比如:class=“container”。

属性描述
class为html元素定义一个或多个类名
id定义元素的唯一id
style规定元素的行内样式
title描述元素的额外信息
 3.2 遍历节点树

  对于soup文档,遍历直接 .name 就可以,这种方式可以一直下钻,这种方法还有一些特殊的属性。

  •   .contents属性:可以将tag的子节点以列表的方式输出:
  •   .children 生成器:可以对tag的子节点进行循环:
  •   .string:如果tag只有一个 NavigableString 类型子节点,那么这个tag可以使用 .string 得到子节点:
  •   .parent:获取某个元素的父节点
  •   .next_element :指向解析过程中下一个被解析的对象(字符串或tag),结果可能与 .next_sibling 相同,但通常是不一样的.
  •   .previous_element:它指向当前被解析的对象的前一个解析对

  示例:

soup
>>>
<!DOCTYPE html>
<html><head>
    <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"/>
    <link href="/favicon.ico" rel="icon" type="image/x-icon"/>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
    <title>【成都英语运营/亚马逊运营_英语运营/亚马逊运营招聘_深圳市宏泰祺科技有限公司】-前程无忧官方招聘网站</title>
</head>
</html>
soup.head.title.string
>>>
'【成都英语运营/亚马逊运营_英语运营/亚马逊运营招聘_深圳市宏泰祺科技有限公司】-前程无忧官方招聘网站'
soup.head.title.parent
>>>
<head>
    <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"/>
    <link href="/favicon.ico" rel="icon" type="image/x-icon"/>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
    <title>【成都英语运营/亚马逊运营_英语运营/亚马逊运营招聘_深圳市宏泰祺科技有限公司】-前程无忧官方招聘网站</title>
</head>
# 这里为啥输出换行符,其实就是网页信息中换行了,虽然在soup中看不到,可以.contents查看
soup.head.title.string.next_element
>>>
'\n    '

  但是上述这些当文档存在多个同名节点时,只能获取第一个,要想获取全部,就需要用到下面的搜索文档树

 3.3 搜索文档树

  这里着重介绍find() 和find_all()方法,其他方法使用与之类似。
  注意,这里的find_all和正则中的findall写法不一样哦

  在讲解find_all之前先介绍过滤器。
在这里插入图片描述
在这里插入图片描述

find_all()

主要参数介绍:
name:name 参数可以查找所有tag,字符串对象会被自动忽略掉。如"a"、"p"等。
keyword 参数:可以理解成属性名 如:id=‘link2’、href=re.compile(“elsie”)、class_=“sister”
注意,这里的class因为是python的关键字,所以加了_

四、 应用

还是选择和上次re一样的需求,便于比较
网址:“https://jobs.51job.com/chengdu/132231033.html?s=sou_sou_soulb&t=0=”
需求:想要获取岗位职责和任职要求数据

test = []
for i in soup.find_all(class_="bmsg job_msg inbox")[0].find_all(['div','p']):
    if i.string:
        test.append(i.string)
test

>>>
['岗位职责:',
 '1. 负责亚马逊的listing管理,平台账号的管理与维护,上传产品,推广产品;',
 '2. 负责客户产品售前、售后所咨询的问题电子邮件回复;',
 '3. 保障公司账户的正常运营,处理好客户的中差评;',
 '4. 负责公司相关市场的产品文案编辑工作;',
 '5. 完成部门领导安排的其他工作。',
 '岗位要求:',
 '1、大专以上学历,英语专四以上证书,商务信函写作熟练,有一年亚马逊客服经验优先;',
 '2、掌握客户服务基本技巧,能灵活、独立解答客户的问题;',
 '3、吃苦耐劳,具有团队精神,认真负责,有较强的学习能力,对B2C外贸工作有浓厚兴趣。']

对比两种方法,re要花大量时间去总结规律,相对复杂,但是总结出来的规律匹配精准度相对准确,而Beautiful根据节点提取快速,但有个别网页不遵守规范,导致提取的准确度相对低,但也可以用。
最好的办法还是两者结合,把正则规则作为find_all 的参数,会大大增加准确性。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值