正则表达式的 Catastrophic backtracking 错误

2017-03-31 15:43:36 +08:00
 SingeeKing

最近在写 python 爬虫抓取 OPAC 的图书列表,有一段 HTML 如下

<div class="bookmeta" bookrecno="166612">
              <div>1 . 
                <span class="bookmetaTitle">
                  <a href="book/166612" target="_blank">
                    数学百科全书.第一卷 A-C
                  </a>
                </span>
                <a href="book/166612" target="_blank">
                  <img border="0" src="/opac/media/images/newwin.png">
                </a>
              </div>
              <div>著者:
                <a href="/opac/search?searchWay=author&amp;q=%E3%80%8A%E6%95%B0%E5%AD%A6%E7%99%BE%E7%A7%91%E5%85%A8%E4%B9%A6%E3%80%8B%E7%BC%96%E8%AF%91%E5%A7%94%E5%91%98%E4%BC%9A%E7%BC%96%E8%AF%91" target="_blank"> 
                  《数学百科全书》编译委员会编译
                </a>
              </div>
              <div>
                出版社: 
                <a href="/opac/search?searchWay=publisher&amp;q=%E7%A7%91%E5%AD%A6%E5%87%BA%E7%89%88%E7%A4%BE" target="_blank"> 
                  科学出版社
                </a>
                &nbsp;
                出版日期: 1994
              </div>
              <div>
                文献类型: 
                
                <img src="/opac/booktypeicon/1" class="booktypeIcon">
                图书, 
                索书号:
                <span class="callnosSpan">O1-61/S661/:1 </span>
              </div>
            </div>

现在想要提取出内部的 书籍编号 (bookrecno) 书名索书号

使用以下正则匹配,匹配到“索书号:”无问题

<div class=\"bookmeta\" bookrecno=\"(\d*?)\">.*?<a href=\"book/\d*?\" target=\"_blank\">\s*(.*?)\s*</a>.*?索书号:

但是想要继续匹配下面的 < 时,使用 \w*< 提示 “ Catastrophic backtracking 错误” 而 .*?< 却无任何问题。求解这个错误到底是什么?

附:

可以正常匹配的正则

<div class=\"bookmeta\" bookrecno=\"(\d*?)\">.*?<a href=\"book/\d*?\" target=\"_blank\">\s*(.*?)\s*</a>.*?索书号:.*?<span class=\"callnosSpan\">\s*(.*?)\s*</span>.*?</div>.*?</div>

提示错误的正则

<div class=\"bookmeta\" bookrecno=\"(\d*?)\">.*?<a href=\"book/\d*?\" target=\"_blank\">\s*(.*?)\s*</a>.*?索书号:\w*<span class=\"callnosSpan\">\s*(.*?)\s*</span>\w*</div>\w*</div>
1370 次点击
所在节点    问与答
5 条回复
ijustdo
2017-03-31 16:44:57 +08:00
python 里 正则库 \w 能匹配换行么?

<div class=\"bookmeta\" bookrecno=\"(\d*?)\">.*?<a href=\"book/\d*?\" target=\"_blank\">\s*(.*?)\s*</a>.*?索书号:\s*<span class=\"callnosSpan\">\s*(.*?)\s*</span>\s*</div>\s*</div>

出错的 改为这样就可以了 注意贪婪模式和非贪婪模式
ijustdo
2017-03-31 16:46:41 +08:00
还有一个技巧就是 不要每次都去编译正则 python 的正则可以 re.compile 编译为一个对象 然后用这个对象去 search 或者 match
ltux
2017-03-31 17:36:35 +08:00
又该上这个链接了
http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/

为什么不用 lxml 或者 beautiful soup 呢?
SingeeKing
2017-03-31 18:03:42 +08:00
@ijustdo 嗯,谢啦;我就是用的 re.compile ,出错之后用 regex101 手动转义的
SingeeKing
2017-03-31 18:03:55 +08:00
@SingeeKing 新手上路。。请多多关照😂

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/351766

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX