2010-08-09 64 views
0

我试图读取并处理网页在Python具有像在它下面几行:阅读网页与Python

   <div class="or_q_tagcloud" id="tag1611"></div></td></tr><tr><td class="or_q_artist"><a title="[Artist916]" href="http://rateyourmusic.com/artist/ac_dc" class="artist">AC/DC</a></td><td class="or_q_album"><a title="[Album374717]" href="http://rateyourmusic.com/release/album/ac_dc/live_f5/" class="album">Live</a></td><td class="or_q_rating" id="rating374717">4.0</td><td class="or_q_ownership" id="ownership374717">CD</td><td class="or_q_tags_td"> 

我目前只在艺术家的名字感兴趣(AC/DC)和专辑名称(Live)。我可以使用libxml2dom来读取和打印它们,但我无法弄清楚如何区分链接,因为每个链接的节点值都是None。

一个显而易见的方法是一次读取输入行,但有没有更聪明的方式来处理这个html文件,以便我可以创建两个单独的列表,其中每个索引匹配另一个或具有此信息的结构?

import urllib 
import sgmllib 
import libxml2dom 

def collect_text(node): 
    "A function which collects text inside 'node', returning that text." 

    s = "" 
    for child_node in node.childNodes: 
    if child_node.nodeType == child_node.TEXT_NODE: 
     s += child_node.nodeValue 
    else: 
     s += collect_text(child_node) 
    return s 

    f = urllib.urlopen("/home/x/Documents/rym_list.html") 

    s = f.read() 

    doc = libxml2dom.parseString(s, html=1) 

    links = doc.getElementsByTagName("a") 
    for link in links: 
    print "--\nNode " , artist.childNodes 
    if artist.localName == "artist": 
     print "artist" 
    print collect_text(artist).encode('utf-8') 

    f.close() 
+1

你能告诉我们你目前的代码吗?也许你需要明确引用anchor的firstChild? (文本节点) – 2010-08-09 15:14:21

+0

我没有看到一次读取输入行有什么问题。 – katrielalex 2010-08-09 15:25:26

+0

只需要注意一下,如果你的for循环可以重复多次:创建新字符串就像地狱一样昂贵(它们是不可变的 - 你最终每次都会创建一个新对象),并且每次迭代都会执行一次。最好追加到列表中,然后在循环后加上'''.join()'列表。它可以使戏剧性的加速。 – Daenyth 2010-08-09 20:21:11

回答

2

由于HTML小的这段,我不知道这是否是完整的网页上有效的,但在这里是如何提取“AC/DC”和“活”使用lxml.etreexpath

>>> from lxml import etree 
>>> doc = etree.HTML("""<html> 
... <head></head> 
... <body> 
... <tr> 
... <td class="or_q_artist"><a title="[Artist916]" href="http://rateyourmusic.com/artist/ac_dc" class="artist">AC/DC</a></td> 
... <td class="or_q_album"><a title="[Album374717]" href="http://rateyourmusic.com/release/album/ac_dc/live_f5/" class="album">Live</a></td> 
... <td class="or_q_rating" id="rating374717">4.0</td><td class="or_q_ownership" id="ownership374717">CD</td> 
... <td class="or_q_tags_td"> 
... </tr> 
... </body> 
... </html> 
... """) 
>>> doc.xpath('//td[@class="or_q_artist"]/a/text()|//td[@class="or_q_album"]/a/text()') 
['AC/DC', 'Live'] 
+0

您可以从http://rateyourmusic.com/collection_p/Makis/oo找到完整的文件,但是您无法直接从该网站读取它,因为它们似乎阻止脚本访问。 – Makis 2010-08-09 19:00:44

+0

您无法直接阅读,因为您需要登录才能阅读。换句话说,除非您发布您的用户名和密码,否则无法阅读。如果你有任何钓鱼网站,你应该发布你的用户名和密码。 – aaronasterling 2010-08-09 19:33:14

+0

哎唷,我没有检查。您可以查看anyones集合,但不能打开可打印页面(其中包含一个页面上的所有相册)。 – Makis 2010-08-10 17:31:23

0
  1. 看看你是否能在JavaScript中使用jQuery风格DOM/CSS选择器来获得在你想要的元素/文本解决问题。
  2. 如果你可以得到一个用于python的BeautifulSoup的副本,你应该在几分钟之内就可以开始。