对网站源码使用正则式的疑问?

2016-05-02 00:12:46 +08:00
 explist
网站: http://sou.kuwo.cn/ws/NSearch?type=all&catalog=yueku2016&key=%E6%B1%AA%E5%B3%B0
要求:爬取其上的歌曲 ID ,歌名,歌手名
我写了个太难看了,如何写得更优雅点,或其它更好的方法
pat = re.compile(r'<p class="m_name">\s+<a href=".+?(\d+)/"\s*title="(.+?)".+?\s+.+?\s+.+?\s+.+?\s+.+?\s+?<p class="s_name".+?title="(.+?)"><')
res = pat.findall(html.read().decode())
另外:如何插入图片啊这里,代码也很乱

源码示例:
<li class="clearfix">
<p class="number"><input type="checkbox" checked="checked" name="musicNum" value="122560" mid="122560" />01</p>

<p class="m_name">
<a href="http://www.kuwo.cn/yinyue/122560/" title="怒放的生命" target="_blank">
<script>document.write("怒放的生命".replace(/(汪峰)/gi,'<em class="redFont">$1</em>'))</script>
</a>
</p>
<p class="a_name"><a href="http://www.kuwo.cn/album/7985/" title="怒放的生命" target="_blank"><script>document.write("怒放的生命".replace(/(汪峰)/gi,'<em class="redFont">$1</em>'))</script></a></p>
<p class="s_name"><a href="http://www.kuwo.cn/mingxing/%E6%B1%AA%E5%B3%B0/" target="_blank" title="汪峰"><script>document.write("汪峰".replace(/(汪峰)/gi,'<em class="redFont">$1</em>'))</script></a></p>
<p class="listen"><a href="http://player.kuwo.cn/MUSIC/MUSIC_122560" title="怒放的生命试听" target="_blank"></a></p>
<p class="video"><a href="http://www.kuwo.cn/mv/122560/" title="怒放的生命 MV" target="_blank"></a></p>
<p class="share"><a href="javascript:void(0);" onclick="showShareMusic(this,'怒放的生命','','122560')" title="分享"></a></p>
<p class="down"><a href="javascript:void(0);" title="怒放的生命下载" onclick="showDownMusic2014('MUSIC_122560');"></a></p>
</li>
4318 次点击
所在节点    Python
40 条回复
fy
2016-05-02 00:41:19 +08:00
比较复杂的 html 就使用 lxml
而且说实话这种东西没什么复杂不复杂的,挂了就修,忘记了就重写,一个正则能顶个十天半个月的,你管他好不好看
just1
2016-05-02 00:53:31 +08:00
value="(\d+)"[\s\S]*(:?"(:?s|a)_name"[\s\S]*?title="(.*)?"){2}
难看,但是短了点
qqmishi
2016-05-02 00:54:03 +08:00
这种可以试试用 bueatifulsoup 解析
我的正则写的比你的更难看,但又不是不能用对吧,,,自用就懒得管优雅不优雅了
icybee
2016-05-02 00:55:10 +08:00
bs,pyquery?
ayaseangle
2016-05-02 01:36:47 +08:00
用 xml 解析方便。。。。
skydiver
2016-05-02 01:38:24 +08:00
大忌就是用正则匹配 html
binux
2016-05-02 06:52:13 +08:00
html 不是正则语言,不符合正则文法
不要用正则解析 html !
不要用正则解析 html !
不要用正则解析 html !
aprikyblue
2016-05-02 07:13:43 +08:00
嗯。。楼上说的很清楚了。
会有各种坑
当然,如果是那种自己用几次就扔的,那当没说
TangMonk
2016-05-02 11:09:53 +08:00
用 xpath 嘛
donghouhe
2016-05-02 11:17:58 +08:00
@binux 大牛,膜拜中.....终于见到活的了
chairuosen
2016-05-02 11:32:56 +08:00
pyquery
explist
2016-05-02 11:40:02 +08:00
哪种方式速度快一点?我的正则实在是太慢了! OMGD
explist
2016-05-02 11:45:11 +08:00
好多都要生成树,而正则表达式写的好的话,会快一些?
jackal
2016-05-02 11:47:31 +08:00
抛开立场之分
(立场之分是指有人要让正则表达式做不该它做的事情,比如解析任意复杂的 html 等)

题主的问题是:希望从数个固定格式的网页数据中抓取固定模式的数据段。 我的意思是,前提条件是 kuwo 的歌曲网页数据都很固定,而且网页中关于歌曲 id ,歌曲名称,歌手名称,都是固定的模式数据( class=“ number ”, class=“ name ” , class=“ s_name ”)

这样,我觉得一个简单的实现,是可以用正则表达式来解析 /抓取数据的。

题主的正则表达式已经可以了,只是 3 点还有问题:
1 )应该遵从 class=“ number ”, class=“ name ” , class=“ s_name ”的格式来抓取对应的数据,而不是从其他地方去获取(以后就算页面改版,很可能 class 的名字和对应数据是不会改变的)

2 )让.*能够匹配换行,这样你的正则表达式中+?\s+.+?\s+.+?\s+.+?\s+.+?\s+?就不要再出现了。

3 )为提高效率,尽量使用普通字符串( plain text )匹配,少用.*+?等符号
N4HS3zwwKs7wira0
2016-05-02 11:51:38 +08:00
jackal
2016-05-02 11:52:49 +08:00
@explist
快还是慢,数据说话。(你可以优化正则表达式,或者再用其他的第三方库 parser 来写一个,然后做一个时间比较, 希望你贴上一个比较数据)

正则表达式并不慢,只要用对地方。
xiamx
2016-05-02 11:54:59 +08:00
Html 是 Context Free Grammar ,不是 Regular Language 所以不能被 Regular expression 识别
explist
2016-05-02 11:55:07 +08:00
@jackal 说得太好了,胜读十年书啊
能不能写个示范出来?
explist
2016-05-02 11:59:48 +08:00
@jackal 贴 个比较数据对新手来说要求有点高啊,以上所说的第三方库都没学习过,还要从头来,只知道一个自带的:
html.parser.HTMLParser
N4HS3zwwKs7wira0
2016-05-02 12:00:26 +08:00
@jackal Regex 不加奇怪的语法是 O(n). Suffix array 可以 O(m), m 是 query string length , n 是 text length 。但现在 Regex 语法太杂,如果不能用 DFA model ,复杂度很容易 blow up.

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

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

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

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

© 2021 V2EX