V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
qsnow6
V2EX  ›  Python

怎样更优雅的过滤 HTML 标签?

  •  
  •   qsnow6 · 2017-02-21 15:06:06 +08:00 · 3157 次点击
    这是一个创建于 2834 天前的主题,其中的信息可能已经有所发展或是发生改变。

    扒页面的时候,经常会遇到这种的需求:

    • 获取页面上所有的文章内容
    • 过滤所有 HTML 标签,仅保留图像及文字

    目前我自己提取网页文字觉得最方便的处理是这样的

        from bs4 import BeautifulSoup
        html_string = "一些 HTML 字符" 
        soup = BeautifulSoup(html_string)
        soup.text
    
    

    但是

    在需要保留 IMG 标签的时候就不行了,这时候我是采用正则来过滤,不过比较丑陋。。。

    每次 coding 都好纠结,不知道有没有好方法,敲代码可以敲得更嗨点;)

    第 1 条附言  ·  2017-02-21 16:02:12 +08:00

    非常感谢 BiggerLonger 提供的这个scrapy里的模块

    from w3lib.html import remove_tags 
    # keep参数为需要保留的标签名称
    remove_tags(text, keep=('img',)) 
    
    12 条回复    2017-02-22 07:50:25 +08:00
    SourceMan
        1
    SourceMan  
       2017-02-21 15:12:39 +08:00
    抽象出来,不就眼不见心不烦?
    HanSonJ
        2
    HanSonJ  
       2017-02-21 15:16:55 +08:00
    PHP: echo strip_tags('一些 HTML 字符');

    别打我 逃)
    IanPeverell
        3
    IanPeverell  
       2017-02-21 15:18:45 +08:00
    可以试试 lxml ,然后用 xpath
    qsnow6
        4
    qsnow6  
    OP
       2017-02-21 15:29:17 +08:00
    @SourceMan 想看有没有现成的,造轮子水平不高。。
    chairuosen
        5
    chairuosen  
       2017-02-21 15:35:29 +08:00
    先用正则把 img 标签找出来,替换成复杂的特殊字符文字包裹的 src 地址 text ,然后用你上文的方法替换其他标签,最后再把 img 标签转回来
    bombless
        6
    bombless  
       2017-02-21 15:36:45 +08:00
    以前做富文本编辑功能的时候做过这样的东西
    用的方式是直接在 DOM 树上操作,递归解出 DOM 列表的内容
    看了下 BeautifulSoup 里面也有 findChildren()这样的操作
    BiggerLonger
        7
    BiggerLonger  
       2017-02-21 15:39:01 +08:00   ❤️ 1
    from w3lib.html import remove_tags
    remove_tags(text, which_ones=('div', 'a', ....))
    scrapy 裡面的一個庫
    qsnow6
        8
    qsnow6  
    OP
       2017-02-21 15:57:55 +08:00
    @BiggerLonger 这个好!!!
    现在就是在用 scrapy 写爬虫

    这样就解决了!!

    ````
    remove_tags(text, keep=('img'))
    ````
    ic2y
        9
    ic2y  
       2017-02-21 16:12:39 +08:00
    用 xpath 进行提取, xpath 可以 专门解析提取 属性。
    murmur
        10
    murmur  
       2017-02-21 16:21:13 +08:00
    想多了 难道不知道图片地址还可以写到 css 么
    xieranmaya
        11
    xieranmaya  
       2017-02-22 01:05:24 +08:00
    jsdom 知道不
    popil1987
        12
    popil1987  
       2017-02-22 07:50:25 +08:00 via Android
    用 lxml ,别用 bs4 。 bs4 只支持 css selector,而且不支持 nth-child 这种。 lxml 支持 xpath,用谷歌浏览器开发者工具可以很方便提取元素的 xpath
    lxml 貌似只有排除一些 tag 的功能,没有保留一些 tag 的功能
    不过可以建立个保留的 tag 名称的集合,遍历所有 node ,把未在集合中的 tag 删了就行。
    当然有种情况是,你想保留 a 但不想保留 b ,那么
    <b><a></a></b>这种情况得需要注意了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   999 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 21:09 · PVG 05:09 · LAX 13:09 · JFK 16:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.