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

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>
4308 次点击
所在节点    Python
40 条回复
explist
2016-05-02 12:02:25 +08:00
@jackal 就是不知道怎么让 . 匹配换行,[.\n] 这样试了不行
explist
2016-05-02 12:08:52 +08:00
这下好了点: r'<p class="m_name">\s+<a href=".+?(\d+)/"\s*title="(.+?)"[\s\S]+?<p class="s_name".+?title="(.+?)"><'
N4HS3zwwKs7wira0
2016-05-02 12:09:15 +08:00
@explist Add (?s) before your regexp.
jackal
2016-05-02 12:14:07 +08:00
我看到非常多的网友在回复中说, 不能用正则表达式来做这件事情。

我已经在我的回复中表达了这一点:“抛开立场之见”, 如果这个任务相对简单,不做其他扩展, 则完全可以用正则表达式来完成。

也请大家在做结论的时候, 切勿简单的思考或者表明立场。 实际上, 不少的网友心里并没有认真思考过, 什么叫合适, 什么叫不合适, 而是简单尊从 StackOverflow 或者某一些结论。

任何正确的结论都有前提条件; 当前提条件不满足了, 正确的就可能变成错误的结论, 希望大家深思。
jackal
2016-05-02 12:32:07 +08:00
@explist 匹配换行符, 使用[\s\S]

不建议从<p class="m_name">里面去抓数据。

衡量性能, 请安装一个 RegexBuddy (这个是收费的)或者有好几个网站提供网页(免费,请自己找一下)来做类似的事情。
cevincheung
2016-05-02 12:36:08 +08:00
xpath 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊!!!!
jarlyyn
2016-05-02 15:18:05 +08:00
@jackal

既然这个观点是你提出来的,那烦请给出范例。

作为一个方面做 mud 机器人正则写到吐,现在写 web 各种 class 混用的人,好奇怎么处理多 class 的 html.

我就不提万一 html 里有注释这种蛋疼的情况了。
fy
2016-05-02 15:59:48 +08:00
@jarlyyn 我觉得没有必要假设网站的作者整天改 html ,以我的经验基本上一改就是全改, xpath 也好 css 选择器也好全都救不回来,老老实实重写。

正则当然是非常简单粗暴了,胜在方便熟练无依赖(lxml 需要二进制或者编译安装)。我觉得根据场景灵活选择吧,没有必要上纲上线。

@explist 匹配的时候,最后一个参数后面加上 re.DOTALL ,点就能匹配换行了
aliipay
2016-05-02 16:22:47 +08:00
@fy lxml 用 xpath 吗?感觉写起来也很难看
binux
2016-05-02 16:32:28 +08:00
@fy 但是他们会没事给加的特效,例如加红加粗加下划线
explist
2016-05-02 16:38:24 +08:00
@just1 失败了
jarlyyn
2016-05-02 18:03:26 +08:00
@fy

这和假设有什么关系, html 就是这样写的啊,随时加个 new 或者 hot 的类
just1
2016-05-02 18:58:02 +08:00
reg='value="(\d+)"[\s\S]*?"a_name"[\s\S]*?title="(.*?)"[\s\S]*?"s_name"[\s\S]*?title="(.*?)"'
eoo
2016-05-02 20:51:15 +08:00
对于一个写 PHP 的我来说 我比较倾向于正则表达式 ,如果用类似 Simple HTML DOM 来解析 HTML 或者引入几十 K 甚至上百 几百 K 的类来解析 HTML 估计内存会挂掉。
bigwahaha
2016-05-02 20:58:42 +08:00
xpath 去解析 html 才是正道,楼主快回来
explist
2016-05-02 21:30:41 +08:00
这样速度快了不少:
re.compile(r'"m_name">.+?/(\d+)/"\s*title="(.+?)".+?s_name".+?title="(.+?)"',re.S)
fy
2016-05-02 22:02:08 +08:00
@aliipay 还好吧,其实也不怎么丑, css 选择器也可以用
xiamx
2016-05-02 22:39:47 +08:00
@jackal "抛开立场之分 (立场之分是指有人要让正则表达式做不该它做的事情,比如解析任意复杂的 html 等) "

正则表达式_不能_解析 html 。 正则能解析的 HTML 只是当前 HTML 文档的一个子集。
52cik
2016-05-03 14:54:50 +08:00
js 的正则是这样的,不知道其他语言能不能跑。
musicNum\D+(\d+)[^(]+\("([^"]+)[^(]+...([^)]+)
$1 是 id ,$2 是歌曲,$3 是歌手
retanoj
2016-05-04 14:58:38 +08:00
我在源码里直接搜索 li class="clearfix 就定位到 n 条歌曲记录
不可以先对源码 parse 一下,然后用 xpath 或者各种选择器去选么?
例如 document.querySelector("li[class='clearfix'] > p[class='m_name'] > a").getAttribute('title')

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

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

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

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

© 2021 V2EX