爬虫笔记3-信息标记提取

信息标记和提取

信息标记的三种形式

  1. XML 最早的通用信息标记语言,可扩展性好,但繁琐。 主要用于 Internet 上的信息交互与传递。
  2. JSON 信息有类型,适合程序处理(js),较 XML 简洁。 主要用于移动应用云端和节点的信息通信,缺点是无注释
  3. YAML 信息无类型,文本信息比例最高,如 name:silas,没有引号标明是字符串。 主要用于各类系统的配置文件,有注释易读。
    1. 缩进表达所属关系 name: newName: mzj oldName: myz
    2. - 表达并列关系 name: - mzj - myz
    3. | 表达整块数据,# 表示注释 text: | # 介绍 abcdefghijklmnopqrstuvwxyz0123456789

信息提取

soup = BeautifulSoup(res.text, 'html.parser')
# 搜索所有 <a> 标签内容
for link in soup.find_all('a'):
    print(link.get('href'))
find_all(name, attrs, recursive, string, **kwargs)

返回一个列表类型,存储查找的结果

  1. name:对标签名称的检索字符串 # 提取一个标签 soup.find_all('a') # 提取多个标签 soup.find_all(['a','div']) # 参数为 True 提取所有标签 for tag in soup.find_all(True): print(tag.name) # 提取所有匹配正则表达式(以 b 开头)的标签 import re for tag in soup.find_all(re.compile('b')): print(tag.name)
  2. attrs:对标签属性值的检索字符串,可标注属性检索 所有 <a> 标签中有 bri 属性的标签。 >>> soup.find_all('a', 'bri') [<a class="bri" href="//www.baidu.com/more/" name="tj_briicon" style="display: block;">更多产品</a>] 所有 id 为 lh 的标签 >>> soup.find_all(id="lh") [<p id="lh"> <a href="http://home.baidu.com">关于百度</a> <a href="http://ir.baidu.com">About Baidu</a> </p>] 所有包含 link 文字的 id,比如 link1alinkb 等 >>> soup.find_all(id=re.compile('link')) []
  3. recursive:是否对子孙全部检索,默认True >>> soup.find_all('a') [<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a>, <a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123</a>, <a class="mnav" href="http://map.baidu.com" name="tj_trmap">地图</a>, <a class="mnav" href="http://v.baidu.com" name="tj_trvideo">视频</a>, <a class="mnav" href="http://tieba.baidu.com" name="tj_trtieba">贴吧</a>, <a class="lb" href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1" name="tj_login">登录</a>, <a class="bri" href="//www.baidu.com/more/" name="tj_briicon" style="display: block;">更多产品</a>, <a href="http://home.baidu.com">关于百度</a>, <a href="http://ir.baidu.com">About Baidu</a>, <a href="http://www.baidu.com/duty/">使用百度前必读</a>, <a class="cp-feedback" href="http://jianyi.baidu.com/">意见反馈</a>] >>> soup.find_all('a',recursive=False) 什么都没有,输出 []
  4. string: 对标签中字符串区域的检索字符串 文档中有 "> <a href="http://home.baidu.com">关于百度</a> <a href="http://ir.baidu.com">About Baidu</a> 这么一条 >>> soup.find_all(string="关于百度") ['关于百度'] 所有含有“百度”的内容 >>> soup.find_all(string=re.compile('百度')) ['百度一下,你就知道', '关于百度', '使用百度前必读']

简写:

<tag>() 等价 <tag>.find_all() soup() 等价 soup.find_all()

扩展方法

方法

说明

<>.find()

搜索且只返回一个结果, 同 .find_all() 参数

<>.find_parents()

在先辈节点中搜索,返回列表类型,同 .find_all() 参数

<>.find_parent()

在先辈节点中返回一个结果,同 .find() 参数

<>.find_next_siblings()

在后续平行节点中搜索,返回列表类型,同 .find_all() 参数

<>.find_next_sibling()

在后续平行节点中返回一个结果,同 .find() 参数

<>.find_previous_siblings()

在前序平行节点中搜索,返回列表类型,同 .find_all() 参数

<>.find_previous_sibling()

在前序平行节点中返回一个结果,同 .find() 参数

实例

爬取 http://www.zuihaodaxue.cn/zuihaodaxuepaiming2018.html 的大学排名并提取信息。

思考步骤:

  1. 打开网页,查看源代码,查找一个大学,比如“清华大学”,定位到代码位置

university.png 一个 <tr> 包含一个大学,具体信息在 <td> 标签中,前四个分别为大学排名,大学名称,所在城市,分数。

  1. 打开 http://www.zuihaodaxue.cn/robots.txt 看网站是否禁止爬取,结果是没有这个文件,所以可以爬取
  2. 定义输出结果,按排名、学校名称、总分排列
  3. 定义方法 getHTMLText() 爬取网页内容
  4. 定义方法 fillUnivList() 将网页内容提取到合适的数据结构中
  5. 定义方法 printUnivList() 将数据结构中内容输出显示
import requests
import bs4

def getHTMLText(url):
    try:
        res = requests.get(url, timeout=30)
        res.raise_for_status()
        res.encoding = res.apparent_encoding
        return res.text
    except:
        return ""

def fillUnivList(ulist, html):
    soup = bs4.BeautifulSoup(html, 'html.parser')
    for tr in soup.find('tbody').children: # 遍历子节点,每个 tr 就是一所大学
        if isinstance(tr, bs4.element.Tag): # 过滤掉不是标签类型的子节点
            tds = tr('td') # 相当于 tr.find_all('td') 找 tr 里面的所有 td
            ulist.append([tds[0].string, tds[1].string, tds[3].string])

def printUnivList(ulist, num):
    tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}"
    print(tplt.format("排名","学校名称","总分",chr(12288)))
    for i in range(num):
        u = ulist[i]
        print(tplt.format(u[0],u[1],u[2],chr(12288)))

def main():
    uinfo = [] # 存储大学信息的列表
    url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2018.html'
    html = getHTMLText(url)
    fillUnivList(uinfo, html)
    printUnivList(uinfo, 20) # 只打印前 20 名大学数据

main()

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券