美文网首页
爬虫笔记3-信息标记提取

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

作者: 三流之路 | 来源:发表于2018-12-27 22:16 被阅读0次

    信息标记和提取

    信息标记的三种形式

    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> 标签中,前四个分别为大学排名,大学名称,所在城市,分数。

    2. 打开 http://www.zuihaodaxue.cn/robots.txt 看网站是否禁止爬取,结果是没有这个文件,所以可以爬取

    3. 定义输出结果,按排名、学校名称、总分排列

    4. 定义方法 getHTMLText() 爬取网页内容

    5. 定义方法 fillUnivList() 将网页内容提取到合适的数据结构中

    6. 定义方法 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()
    

    相关文章

      网友评论

          本文标题:爬虫笔记3-信息标记提取

          本文链接:https://www.haomeiwen.com/subject/dhqjlqtx.html