请帮我入门lxml
我正在学习Python,觉得《Learn Python the Hard Way》、《A Byte of Python》和《Head First Python》这些书都非常不错。不过,现在我想开始一个“真正”的项目,使用lxml让我感觉自己完全是个菜鸟。
我想做的事情(目标)
我想解析一个关于政治的新闻网站的文章。
网址是 http://politiken.dk/politik/
最终的项目应该:
- 1) 每天(也许每小时)访问上面的URL。
- 2) 对于每篇相关的文章,我想把它的URL保存到数据库里。相关的文章在一个
<div class="w460 section_forside sec-forside">
中。有些元素有图片,有些没有。
我想保存以下内容:
- a - 标题 (
<h1 class="top-art-header fs-26">
) - b - 副标题 (
<p class="subheader-art">
) c - 如果元素有对应的图片,那么保存“alt”或“title”属性。
3) 访问每个相关的URL,抓取文章的正文并保存到数据库。
- 4) 如果相关的URL已经在数据库中,就跳过这个URL(上面定义的相关文章总是最新发布的10篇)。
期望的结果是一个数据库表,字段包括:
- art.i) ID
- art.ii) URL
- art.iii) 标题
- art.iiii) 副标题
- art.iiiii) 图片alt
- art.iiiiii) 文章正文。
- art.iiiiiii) 日期和时间(在
<span class="date tr-upper m-top-2">
中的字符串)。
以上就是我希望得到帮助的内容。由于屏幕抓取并不总是友好的,我想解释一下我为什么想这么做。
基本上,我想挖掘数据,看看议员或政党的出现频率。我不会重新发布这些文章,也不会出售数据之类的(我没有检查我的做法是否合法,但希望并认为应该是合法的)。
我想象中有一个政治家表和一个政党表。
对于每个政治家,我会有:
- pol.i) ID
- pol.ii) 名字
- pol.iii) 姓氏
- pol.iiii) 政党
对于每个政党,我会有:
- party.i) ID
- party.ii) 正确名称
- party.iii) 常用名称
- party.iiii) 缩写
我想对几个丹麦的新闻网站做这个,然后分析是否某个报纸偏向某些政治家/政党——简单来说就是根据提及次数来判断。
这也是我需要帮助的地方——但一步一步来:-)
之后我想探索NLTK和情感挖掘的可能性。
我想看看这是否能变成一个政治学/新闻学的博士项目。
这基本上就是我现在的情况(也就是没什么)
我真的很难理解lxml、元素的概念、不同的解析方式等等。当然,我读过教程,但还是很困惑。
import lxml.html
url = "http://politiken.dk/politik/"
root = lxml.html.parse(url).getroot()
# this should retur return all the relevant elements
# does not work:
#relevant = root.cssselect("divi.w460 section_forside sec-forside") # the class has spaces in the name - but I can't seem to escape them?
# this will return all the linked artikles headlines
artikler = root.cssselect("h1.top-art-header")
# narrowing down, we use the same call to get just the URLs of the articles that we have already retrieved
# theese urls we will later mine, and subsequently skip
retrived_urls=[]
for a in root.cssselect("h1.top-art-header a"):
retrived_urls.append(a)
# this works.
我希望从回答中得到什么
首先,只要你不骂我(这很糟糕),我就会很高兴。
- 但我真正希望的是能有一个简单易懂的lxml工作原理的解释。如果我知道该用什么工具来完成上述任务,那我就能更轻松地“深入lxml”。也许是因为我注意力不集中,现在读一些超出我理解能力的内容让我感到失望,我甚至不确定自己是否在找对地方。
- 如果你能提供一些适合某些任务的示例代码,那就太好了。我希望把这个项目变成博士项目,但我确信这种事情已经做过无数次了?如果是这样,我的经验是向他人学习是变得更聪明的好方法。
- 如果你觉得我应该放弃lxml,使用比如scrapy或html5lib,请直接告诉我:-) 我开始研究html5lib,因为Drew Conway在一篇关于政治科学家的Python工具的博客中提到过,但我找不到入门级的材料。另外,lxml是scraperwiki推荐的。至于scrapy,这可能是最好的解决方案,但我担心scrapy太像一个框架——如果你知道自己在做什么并想快速完成,那确实很好,但可能不是学习Python魔法的最佳方式。
- 我计划使用关系数据库,但如果你认为比如mongo会有优势,我会改变我的计划。
- 由于我无法在Python 3.1中安装lxml,所以我正在使用2.6。如果这样做不对,请告诉我。
时间框架
我在stackoverflow上问了很多初学者的问题。多得让我不敢自豪。但由于我有一份全职工作,我似乎总是无法沉浸在代码中,吸收我渴望的技能。我希望这是一个我可以定期回来看并更新我所学内容的问题/答案,这也意味着这个问题可能会保持活跃很长时间。但我会对每个我可能幸运地收到的回答进行评论,并不断更新“我得到了什么”部分。
目前我觉得我可能咬得太多了——所以现在我要回去看《Head First Python》和《Learn Python the Hard Way》。
最后的话
如果你能看到这里——你真棒——即使你不回答问题。你已经读了很多简单、困惑和愚蠢的问题(我为问这些问题感到自豪,所以别争论)。你应该喝杯咖啡,抽根烟,祝贺自己:-)
节日快乐(在丹麦,我们庆祝复活节,现在阳光明媚,就像《低俗小说》中塞缪尔·杰克逊的钱包一样闪亮)。
编辑
看起来BeautifulSoup是个不错的选择。不过开发者表示,如果我想使用Python3,BeautifulSoup并不是一个好选择。但根据这个链接,我更倾向于使用Python3(不过不是特别强烈)。
我还发现《Dive Into Python 3》中有一个关于lxml的章节。我也会去看看。
2 个回答
现在,lxml绝对是解析HTML的首选工具。
这里有一份lxml的速查表,可以帮助你找到很多答案:
http://scraperwiki.com/docs/contrib/python_lxml_cheat_sheet/
你写的那段代码可以直接使用,并且可以在ScraperWiki的编辑窗口中运行。 http://scraperwiki.com/scrapers/andreas_stackoverflow_example/edit/
通常,一个链接的格式是: <a href="链接">标题</a>
在用lxml解析后,你可以通过以下方式获取链接: a.attrib.get("href") 而获取文本则可以用 a.text
不过,在这个特定的情况下,链接的格式是: <a href="链接"> <span> </span> 标题</a> 所以,a.text的值只代表了'<a href="链接">'和第一个'<span>'之间的字符。
但是你可以使用以下代码,通过递归遍历子元素(在这个例子中是<span>)来简化处理:
def flatten(el):
result = [ (el.text or "") ]
for sel in el:
result.append(flatten(sel))
result.append(sel.tail or "")
return "".join(result)