xpath依据条件解析抽取网页中的需要的数据的方法:使用的软件包,lxml其中的etree.HTML方法用于将格式化过的包含HTML数据的.xml文件处理成可供xpath正确处理的节点树, codecs这个软件包的功能不详!!, chilkat用于将html文件格式化成标准的xml文件(即标签的开关是严格对应的)。
xpath处理的最好是.xml后缀的文件,尝试了下html后缀的文件,即使内容完全相同也会出问题。至于不同的数据可能会有不同的结果,下次有机会在测试下这个基于简单实践的推断是否正确好了。
不多说贴代码
from lxml import etree, html import os import urllib from os import path import sys import chilkat import libxml2 import hashlib import codecs from lxml import etree cacheDir = 'News163' if not path.exists(cacheDir): os.makedirs(cacheDir) class xpathHtmlToXml: #转换html,至xml;即html的格式化 def convertHtmlToXml(self, fileName): htmlToXml = chilkat.CkHtmlToXml() # Any string argument automatically begins the 30-day trial. success = htmlToXml.UnlockComponent("30-day trial") if (success != True): print htmlToXml.lastErrorText() sys.exit() # Indicate the charset of the output XML we'll want. htmlToXml.put_XmlCharset("utf-8") sucFile = fileName + '.html' destFile = fileName + '.xml' success = htmlToXml.ConvertFile(sucFile, destFile) if (success != True): print htmlToXml.lastErrorText() else: print "Success" #end def #通过url得到xml文件,即将网页html数据格式化后,存在本地的xml文件中 def getXmlWithUrl(self, urlSrc): digest = hashlib.md5(urlSrc).hexdigest() filePath = path.join(cacheDir, digest) fileHtml = filePath + '.html' fileXml = filePath +'.xml' if not path.exists(fileHtml): htmSrc = urllib.urlopen(urlSrc).read() fileHandle = open(fileHtml, 'w') fileHandle.write(htmSrc) fileHandle.close() if not path.exists(fileXml): self.convertHtmlToXml(filePath) return fileXml #end def #获取指定目录下包含的所有url def GetUrlList(self,useed, principle): urlList = [] urlSeed = useed doc = libxml2.parseFile(self.getXmlWithUrl(urlSeed)) for url in doc.xpathEval(principle): urlList.append(url.content) doc.freeDoc() return urlList #end def #提取单个url页面中的数据 def ParseSingleUrl(self, singleUrl): print singleUrl + ' begin' file=self.getXmlWithUrl(singleUrl) f = codecs.open(file, "r", "utf-8") content=f.read() tree = etree.HTML(content) nodes = tree.xpath(u"//a/@href") for n in nodes: print n print singleUrl + ' end\n\n' #end def htx=xpathHtmlToXml() htx.ParseSingleUrl('http://news.163.com/')
测试用例:
在上面的测试用例中,xmlns="http://www.w3.org/1999/xhtml"这个属性成了了在libxml2中解析的关键问题。把这个属性删掉后能够正常解析,但是如果加上就无法解析。
<?xml version="1.0" encoding="utf-8" ?>
<root>
<html>
<head>
<a href="http://war.163.com"></a>
</head>
</html>
</root>