为什么爬虫大佬多用 re 而少用 soup、xml 来提取元素? - V2EX
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
crella
V2EX    Python

为什么爬虫大佬多用 re 而少用 soup、xml 来提取元素?

  •  
  •   crella 2020-05-11 19:44:29 +08:00 via Android 7978 次点击
    这是一个创建于 1983 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我也知道:先问是不是,再问为什么。

    最近找了几个 python 爬虫来看,它们都是单文件解决从抓取到存储、生成结果的整个流程的。我发现一些大佬经常用 re 等正则表达式匹配元素,而我如果要提取那些元素,只想慢慢地用 xml 或者 json 相关的解析库。

    我个人感觉正则表达式的匹配命令相对较长,而且感觉不好调试的样子。有时候网页上部分标签内的内容为空,不知道正则表达式是怎么处理这些异常的。

    而使用 xml 或 json 配套库的缺点是如果由于网站服务器设置问题或者网络不好,导致下载的页面文本不完整,丢了部分标签,整个 xml 或 json 就解析不了了。而正则表达式则能避免这种问题。

    不知道各位怎么看?
    45 条回复    2020-05-15 11:59:28 +08:00
    ruby0906
        1
    ruby0906  
       2020-05-11 19:49:15 +08:00
    自从我知道了 Xpath 以后,其它方式都渣渣。。
    ClericPy
        2
    ClericPy  
       2020-05-11 19:52:05 +08:00
    1. 正则熟练以后更灵活, 零宽断言什么的, 如果是 css 选择器之类的, 就没法用 Xpath 里那种 contain text 的语法

    2. 没有三方依赖

    3. 性能领先太多了

    PS: lxml 会自动修复不完整的标签, 这点实际比正则还准确点
    zhustec
        3
    zhustec  
       2020-05-11 21:53:25 +08:00 via Android
    xpath 好用 +1
    用正则一般只在比较简单的时候,复杂的时候还用正则可能纯粹只是为了炫技
    ChulianCheng
        4
    ChulianCheng  
       2020-05-11 22:19:24 +08:00 via Android   3
    我用 xpath+jsoup,对了,我用 java 写爬虫
    coloz
        5
    coloz  
       2020-05-11 22:25:41 +08:00
    直接选择器就行了,哪里不会点哪里,无脑写爬虫,效果很好
    dsg001
        6
    dsg001  
       2020-05-11 22:43:15 +08:00
    能用简单正则搞定的何必麻烦,稍微复杂的 css,最后才是 xpath
    LZSZ
        7
    LZSZ  
       2020-05-11 22:49:58 +08:00
    可能是性能 猜的
    python30
        8
    python30  
       2020-05-11 23:03:14 +08:00
    习惯了 xpath + re 一起用
    fbcskpebfr
        9
    fbcskpebfr  
       2020-05-11 23:04:27 +08:00
    我说一个反例,我之前爬豆瓣遇到的。
    在详情页面,发现了只有少数电源,比如妇联,才会有 [官方网站] 这一条信息
    而其他的电影都没有
    之前用 xpath 爬出来几个错位就是这么出来的
    Les1ie
        10
    Les1ie  
       2020-05-11 23:13:34 +08:00
    只用 xpath 基本能解决遇到的问题,如果有不能搞定的地方就加上 re
    malone6
        11
    malone6  
       2020-05-11 23:17:06 +08:00 via Android
    我之前写爬虫经历
    1. 最开始是 re,后来发现 re 写着比较累,过段时间回去看就看不懂这段正则,也容易写错。
    2. 后来用 beautifulsoup,比较语义化,简单,但是代码会写的比较长。
    3. bs 之后对 html 理解变熟练了,就都是用 lxml+xpath 取,包括用 scrapy 的解析器也选择 lxml,当然也会掺和一点简单正则。
    anexplore
        12
    anexplore  
       2020-05-11 23:19:45 +08:00
    简单的用 re 还行,复杂的抽取还是 xpath 好用且易维护。。。说性能,正则表达式写不好性能就是渣渣;
    hakono
        13
    hakono  
       2020-05-12 00:57:38 +08:00 via Android
    在需求稍微复杂点的情况下,爬虫里依旧用正则的,大部分都是新手
    alexkkaa
        14
    alexkkaa  
       2020-05-12 06:04:03 +08:00 via Android
    re 更有通用性,很多情况 dom xpath 无法匹配。
    XIVN1987
        15
    XIVN1987  
       2020-05-12 07:38:32 +08:00 via Android
    看来 xpath 比较流行啊,,了解下去,,
    以前只用过 pyquery
    gleymonkey
        16
    gleymonkey  
       2020-05-12 07:48:58 +08:00
    我倒是觉得 bs4 更简单
    clague
        17
    clague  
       2020-05-12 07:58:56 +08:00 via Android
    正则通用而且性能高
    koebehshian
        18
    koebehshian  
       2020-05-12 08:19:07 +08:00
    用 jquery 那样的匹配语法不是蛮好的
    DelayNoMay
        19
    DelayNoMay  
       2020-05-12 08:23:46 +08:00   1
    谷歌浏览器的 xpath helper 真的很香,对了,我是用 golang 爬虫的
    392039757
        20
    392039757  
       2020-05-12 08:46:12 +08:00   1
    java,python 爬虫都写过,xpath,css 在提取方式上更接近 html 的结构,只有在 xpath,css 不好处理的时候才会选择使用正则提取,一般情况下是使用 xpath,css 提取到 Element 之后再使用正则
    renmu
        21
    renmu  
       2020-05-12 08:49:52 +08:00 via Android
    正则没有依赖,但是维护的时候完全不知道当时怎么写的了
    zengxs
        22
    zengxs  
       2020-05-12 09:20:02 +08:00
    css selector + xpath + regex 都写,使用顺序也是按这个,优先使用 css selector,这个解决不了才考虑下一种方案
    aaronhua
        23
    aaronhua  
       2020-05-12 09:21:57 +08:00
    同上 lxml 加 re
    fancy111
        24
    fancy111  
       2020-05-12 09:23:26 +08:00   1
    xpath 都这么多年了竟然还在说。
    爬基本的东西随便你用哪个方式都差不多,有反爬的这些都没用。
    warcraft1236
        25
    warcraft1236  
       2020-05-12 09:33:29 +08:00
    做过 UI 自动化的基本上不推荐用 xpath 吧,这玩意速度慢
    xpresslink
        26
    xpresslink  
       2020-05-12 09:34:19 +08:00   1
    说句心里话,这个并没有什么一定之规,每个方法都有其局限性,要权衡利弊选择。所以都要能熟练使用。
    dbow
        27
    dbow  
       2020-05-12 09:40:37 +08:00
    xpath 性能比较差,不推荐大规模抓取使用, 正则其实写好了才会比较快。
    aaa5838769
        28
    aaa5838769  
       2020-05-12 09:41:36 +08:00
    Xpath+1 但是感觉用正则比较好一些,
    xuminzhong
        29
    xuminzhong  
       2020-05-12 09:46:12 +08:00 via Android
    @zengxs 正解。
    我也是这样,不过我的框架要强大很多,script 、JSON 、AJAX 都支持,而且可以用链式一行搞定。
    如果只是简单的新闻或 blog 类型页面,可以自动提取,不需要写规则。
    shawndev
        30
    shawndev  
       2020-05-12 10:04:12 +08:00   1
    因为对于主要精力不是爬虫的工程师,日常用到 regex 的机会更多,故而更熟悉。
    XIVN1987
        31
    XIVN1987  
       2020-05-12 10:08:22 +08:00
    @shawndev
    对,,在编辑器里搜索文本内容时经常使用正则,,
    paoqi2048
        32
    paoqi2048  
       2020-05-12 10:08:40 +08:00
    xpath 也不错
    keepeye
        33
    keepeye  
       2020-05-12 10:10:09 +08:00
    正则挺好的啊 用习惯了
    locoz
        34
    locoz  
       2020-05-12 10:40:56 +08:00
    不存在“多用 re 而少用 soup 、xml 、json 相关解析库”,都是看情况使用的。
    结构简单、字段少、不需要考虑复用和增加字段问题,那就正则呗,简单粗暴一行搞完。
    结构复杂、字段多、还需要考虑到后续其他地方复用,并且还有可能会需要增加字段,那你用正则不是写到头秃?而且出个问题还很难解决,后续看还不一定看得懂。

    再说了,如果数据本来就是 JSON 、XML 、HTML,并且你提取的东西也都存在于结构体里面,那为什么不采用对应的解析库解析成 dict/list 再操作呢?说实在的,就那点性能损耗,根本不值一提,通常还没生成个加密参数花的时间多。用对应的解析库提升出来的开发效率(比如自动按路径生成解析代码)和可维护性(要在某个字段下增加获取子字段)更有价值。

    所以通常来说正则的使用场景更多地是补充那些专门的解析库处理不了的场景,比如:
    HTML 里嵌了个当成 JSON 使用的 Javascript Object,并且和其他代码混在同一个标签里,那当然是用正则直接提出来再调用 JS 把它转成 JSON 字符串再处理更方便。要不然你一个一个提取字段,后面维护起来直接爆炸。
    Cmdhelp
        35
    Cmdhelp  
       2020-05-12 10:52:40 +08:00
    re 处理不规整网页比较好,效率也高

    soup 、xml 只适合处理相当规整的网页
    SlipStupig
        36
    SlipStupig  
       2020-05-12 11:32:05 +08:00
    身边的统计学
    CRVV
        37
    CRVV  
       2020-05-12 12:38:50 +08:00
    因为有一些人非常喜欢用正则表达式
    'a b c'.split(' ') 要用 (.*)\ (.*)\ (.*)
    判断一个长度是 10 的 hex 字符串要用 [0-9a-f]{10}
    凡是处理字符串的事情,他们都要上正则表达式。

    从 html 或者 json 里提取数据也是处理字符串,他们当然要上正则表达式了。

    至于这样做到底合不合适,有一个著名的 stackoverflow
    https://stackoverflow.com/questions/1732348
    neoblackcap
        38
    neoblackcap  
       2020-05-12 13:55:44 +08:00
    用正则能解决大多数文字提取的工作,不过你了解编译原理的话。你就知道不是什么语言都是 RE 语言,不能完全用正则表达式正确解析
    bulabean
        39
    bulabean  
       2020-05-12 14:40:12 +08:00
    习惯 xpath +re,bs 只是名气大而已
    JCZ2MkKb5S8ZX9pq
        40
    JCZ2MkKb5S8ZX9pq  
       2020-05-12 16:04:52 +08:00
    xpath 之类的需要先把 xml 结构提取一遍,效率是受点影响。但可读性往往比较好。
    正则快,但可读相比就差点。
    容错其实差不多,结合可读的话,感觉还是 xpath 好点。
    chengxiao
        41
    chengxiao  
       2020-05-13 06:56:55 +08:00
    主要就是 xpath 写的快啊,看两眼结构,就能取出数据
    另外推荐个 Chrome 插件 Xpath Helper 用了 2 年了,很爽
    https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl
    whusnoopy
        42
    whusnoopy  
       2020-05-13 10:04:58 +08:00
    我自己的经历(从大概 07 年开始用 Python 写爬虫)

    先用 BeautifulSoup,发现对很多不严格按规范写的 HTML 无法解析或解析出错,且性能似乎有点堪忧(那时候好像还是 2 还是 3 )
    然后用 pyquery,类似 jQuery 的选择器,在对不按规范写的 HTML 似乎会好一点
    后面发现这几个都会依赖 lxml,然后这个东西在 Windows 下有时候会安装不成功,为了保证代码四处可用,尽可能减少依赖,能用原生 re 就用 re 了
    codeli
        43
    codeli  
       2020-05-13 20:30:15 +08:00
    太消耗资源
    llsquaer
        44
    llsquaer  
       2020-05-14 11:40:22 +08:00
    前段时间刚好将 xpath 改为 re....发现效率突然提升不少呢...原来不用 re 就是写不好啊..后来熟练点了.发现原来是没理解到 re 所以没用..现在发现普通的就直接 re,速度又快..混合使用提高效率
    ZoeYn
        45
    ZoeYn  
       2020-05-15 11:59:28 +08:00
    我到现在还只会(.*?)
    不过我现在爬虫都是请求接口返回 json 数据就很舒服(虽然找接口和参数也很头疼)
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1001 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 18:39 PVG 02:39 LAX 11:39 JFK 14:39
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86