使用Python轻松收集Web站点数据(1)(2)
处理结果
现在,我们已经完成了对mechanize的操作;剩下的工作是理解在fetch()循环期间保存的大量HTML文件。批量处理特性让我能够在一个不同的程序中将这些文件整齐、明显地分离开来,fetch()和process()可能交互得更密切。BeautifulSoup使得后期处理比初次获取更加简单。对于这个批处理任务,我们希望从获取的各种Web页面的零散内容中生成表式的以逗号分隔的值CSV)数据。
- 清单2.使用BeautifulSoup从无序的内容中生成整齐的数据
- fromglobimportglob
- fromBeautifulSoupimportBeautifulSoup
- defprocess():
- print"!MOVIE,DIRECTOR,KEY_GRIP,THE_MOOSE"
- forfnameinglob('result_*'):
- #PutthatsloppyHTMLintothesoup
- soup=BeautifulSoup(open(fname))
- #Trytofindthefieldswewant,butdefaulttounknownvalues
- try:
- movie=soup.findAll('span',{'class':'movie_title'})[1].contents[0]
- exceptIndexError:
- fname="UNKNOWN"
- try:
- director=soup.findAll('div',{'class':'director'})[1].contents[0]
- exceptIndexError:
- lname="UNKNOWN"
- try:
- #Maybemultiplegripslisted,keyoneshouldbeinthere
- grips=soup.findAll('p',{'id':'grip'})[0]
- grips="".join(grips.split())#Normalizeextraspaces
- exceptIndexError:
- title="UNKNOWN"
- try:
- #HidesomestuffintheHTML<meta>tags
- moose=soup.findAll('meta',{'name':'shibboleth'})[0]['content']
- exceptIndexError:
- moose="UNKNOWN"
- print'"%s","%s","%s","%s"'%(movie,director,grips,moose)
第一次查看BeautifulSoup,process()中的代码令人印象深刻。读者应当阅读有关文档来获得关于这个模块的更多细节,但是这个代码片段很好地体现了它的整体风格。大多数soup代码包含一些对只含有格式良好的HTML的页面的.findAll()调用。这里是一些类似DOM的.parent、nextSibling和previousSibling属性。它们类似于Web浏览器的“quirks”模式。我们在soup中找到的内容并不完全是一个解析树。
结束语
诸如我之类的守旧者,甚至于一些更年轻的读者,都会记住使用TCLExpect或使用用Python和其他许多语言编写的类似内容)编写脚本带来的愉悦。自动化与shell的交互,包括telnet、ftp、ssh等等远程shell,变得非常的直观,因为会话中的所有内容都被显示出来。
Web交互变得更加细致,因为信息被分为头部和内容体,并且各种相关的资源常常通过href链接、框架、Ajax等被绑定在一起。然而,总的来说,您可以使用wget之类的工具来检索Web服务器提供的所有字节,然后像使用其他连接协议一样运行与Expect风格完全相同的脚本。
在实践中,几乎没有编程人员过分执着于过去的老方法,比如我建议的wget+Expect方法。Mechanize保留了许多与出色的Expect脚本相同的东西,令人感觉熟悉和亲切,并且和Expect一样易于编写如果不是更简单的话)。
Browser()对象命令,比如.select_form()、.submit()和.follow_link(),真的是实现“查找并发送”操作的最简单、最明显的方法,同时绑定了我们希望在Web自动化框架中具备的复杂状态和会话处理的所有优点。
评论关闭