V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
HeyDMCreally
V2EX  ›  正则表达式

Python 写爬虫,正则式匹配总是有问题求解答

  •  
  •   HeyDMCreally · 2015-12-05 21:04:17 +08:00 · 1940 次点击
    这是一个创建于 3312 天前的主题,其中的信息可能已经有所发展或是发生改变。

    pattern = re.compile('<div.?author.?title="(.*?)"',re.S)

    pattern = re.compile('<div.*?class="content">(.*?)</div>',re.S)

    pattern = re.compile('<i.*?class="number">(.*?)</i>',re.S)

    以上注释的正常出结果
    pattern = re.compile('<div.*?author.*?title="(.*?)".*?<div.*?class=".*?<div.*?class="content">(.?)</div>.?<i.*?class="number">(.*?)</i>',re.S)
    三个合起来的不出结果,不知是什么问题
    后面试着改了几次,结果有几次输出八进制
    这是写的爬糗百的。。,求指点

    15 条回复    2015-12-06 01:36:01 +08:00
    halfcrazy
        1
    halfcrazy  
       2015-12-05 21:46:34 +08:00
    HeyDMCreally
        2
    HeyDMCreally  
    OP
       2015-12-05 22:11:45 +08:00
    @halfcrazy 谢谢 不过问题纠结了很久 想知道是哪里表达错了
    halfcrazy
        3
    halfcrazy  
       2015-12-05 22:15:13 +08:00
    @halfcrazy 方便把要匹配的字串贴出来么
    iEverX
        5
    iEverX  
       2015-12-05 22:59:28 +08:00
    @HeyDMCreally 发一个你要匹配的字符串,就是你程序里面的 content
    lecher
        6
    lecher  
       2015-12-05 23:26:59 +08:00
    我也犯过类似的错误,正则尽量不要用(.*)这样会导致最长匹配,结果就是本意是匹配一串列表的最终匹配出一大段 html 代码。

    如果用正则,最好拆分一下,比如要匹配<div class="style1">一大段列表<li></li></div>就先用正则把这个 div 的内容取出来,再对里面的内容进行正则处理。
    iyaozhen
        7
    iyaozhen  
       2015-12-05 23:31:55 +08:00
    跨行匹配的问题?

    .*? -> [/s/S]*?
    HeyDMCreally
        8
    HeyDMCreally  
    OP
       2015-12-05 23:33:01 +08:00
    bdbai
        9
    bdbai  
       2015-12-05 23:58:08 +08:00 via iPhone
    @lecher .*? 大法好
    Victor215
        10
    Victor215  
       2015-12-06 00:08:15 +08:00 via Android
    这东西分开还能看明白 合起来完全不知道是什么鬼,就算你改好了 放一段时间回来看我相信你肯定也是看不懂的 能简单的分开的就不要合并起来 我觉得能多匹配几次匹配出来就行
    popok
        11
    popok  
       2015-12-06 00:29:45 +08:00
    @HeyDMCreally 根据你 8 楼的内容,写的。
    title="(.*)">\s<h2>.*</h2>\s</a>\s</div>\s+<div class="content">\s+(.*)\s+<!--\d+-->\s+</div>\s+<div class="stats">\s+<span class="stats-vote"><i class="number">(\d+)</i
    popok
        12
    popok  
       2015-12-06 00:31:59 +08:00
    能分开匹配还是分开比较好点
    我的方法是,先 content 写入测试工具,然后把需要匹配那段复制出来,写到正则那栏,然后把其中变化的部分都用正则表示,然后换行都改成\s+,然后就能用了。

    当然这种都是傻瓜方法,根本不谈性能
    HeyDMCreally
        13
    HeyDMCreally  
    OP
       2015-12-06 00:58:02 +08:00
    @popok 谢谢
    imn1
        14
    imn1  
       2015-12-06 01:14:37 +08:00
    python 的正则不知道是 BUG 还是特殊,当多个不确定子匹配(如.*此类涵盖全部的方式),往往得到的结果为空或不可预想
    试过相同的正则在 php 获得结果,但 py 就不行
    所以应该尽可能使用可确定的匹配,例如 [^"]+ 或者 [^<]+ 等写法
    vmebeh
        15
    vmebeh  
       2015-12-06 01:36:01 +08:00
    <div\sclass\="author.+?title="(.+?)">.+?<div\sclass\="content">(.+?)</div>.+?class\="number">(\d+)</i>

    把你的改了一下可用
    <div.*?author.*?title="(.*?)".*?<div.*?class="content">(.+?)</div>.+?<i.*?class="number">(.*?)</i>
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1014 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 18:47 · PVG 02:47 · LAX 10:47 · JFK 13:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.