爬虫解析之css,xpath语法
一、xpath语法
xpath实例文档
<?xml version="1.0" encoding="ISO-8859-1"?> <bookstore> <book> <title lang="eng">Harry Potter</title> <price>29.99</price> </book> <book> <title lang="eng">Learning XML</title> <price>39.95</price> </book> </bookstore>
选取节点
XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。
下面列出了最有用的路径表达式:
实例
在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:
谓语(Predicates)
谓语用来查找某个特定的节点或者包含某个指定的值的节点。
谓语被嵌在方括号中。
实例
在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:
选取未知节点
XPath 通配符可用来选取未知的 XML 元素。
实例
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
选取若干路径
通过在路径表达式中使用“|”运算符,您可以选取若干个路径。
实例
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
Xpath轴
轴可以定义相对于当前节点的节点集
练习
选取所有 title 下面的例子选取所有 title 节点: /bookstore/book/title 选取第一个 book 的 title 下面的例子选取 bookstore 元素下面的第一个 book 节点的 title: /bookstore/book[1]/title 下面的例子选取 bookstore 元素下面的第一个 book 节点的 title: xml.setProperty("SelectionLanguage","XPath"); xml.selectNodes("/bookstore/book[1]/title");
选取所有价格 下面的例子选取 price 节点中的所有文本: /bookstore/book/price/text() 选取价格高于 35 的 price 节点 下面的例子选取价格高于 35 的所有 price 节点: /bookstore/book[price>35]/price 选取价格高于 35 的 title 节点 下面的例子选取价格高于 35 的所有 title 节点: /bookstore/book[price>35]/title
二、CSS语法
提取内容
1) 按照审查元素的写法不一定正确,要按照网页源码的才行 因为不一样,网页源码才是你看到的 2) 浏览器有自带的复制xpath功能,firefox下载firebug插件 3) xpath有c的速度,所以按照[@class=""]准确性较高
爬虫实战xpath和css
class DrugInfo(object): """ 提取的药品信息: self.drug_name #药品名称 self.category #药品类型 self.cite #国家标准 self.company #生产厂家 self.address #厂家地址 self.license_number #批准文号 self.approval_date #批准日期 self.form_drug #剂型 self.spec #规格 self.store #储存方法 self.period_valid #有效期限 self.attention_rank #关注度排名 self.indication #适应症 self.component #成分 self.function #功能主治 self.usage_dosage #用法用量 self.contraindication #禁忌症 self.special_population #特殊人群用药 self.indications #适应症概况 self.is_or_not_medical_insurance #是否属于医保 self.is_or_not_infections #是否有传染性 self.related_symptoms #相关症状 self.related_examination #相关检查 self.adverse_reaction #不良反应 self.attention_matters #注意事项 self.interaction #药物相互作用 self.pharmacological_action #药理作用 self.revision_date #说明书修订日期 self.drug_use_consult #用药咨询 self.drug_use_experience #用药经验 """ def __init__(self,drug): drug_dir = os.path.join(drug_path, drug) self.drug_name = re.findall('(.*?)\[\d+\]',drug)[0] self.drug_id = re.findall('.*?\[(\d+)\].*',drug)[0] self.drug_dir = drug_dir self.drug_use_experience = '' self.drug_use_consult = '' self.file_list = os.listdir(self.drug_dir) self.logger = Logger() self.result = True self.dispatch() if self.drug_use_consult.__len__()==0:self.drug_use_consult = '无' if self.drug_use_experience.__len__()==0:self.drug_use_experience = '无' def dispatch(self): for file in self.file_list: if file.endswith('药品概述.html'): self.drug_summary(self.file_path(file)) elif file.endswith('详细说明书.html'): self.drug_instruction(self.file_path(file)) elif re.match('.*?用药咨询.*',file): self.drug_consultation(self.file_path(file)) elif re.match('.*?用药经验.*',file): self.drug_experience(self.file_path(file)) else: self.result = False break def file_path(self,file): return os.path.join(self.drug_dir,file) def read_file(self,file): with open(file,'r') as f: html = f.read() return html def drug_summary(self,file): """药品概况""" html = self.read_file(file) selector = Selector(text=html) self.category = selector.xpath('//div[@class="t1"]/cite[1]/span/text()').extract_first() #药品类型 if not self.category: self.category = '未知' self.cite = selector.xpath('//div[@class="t1"]/cite[2]/span/text()').extract_first() #国家标准 if not self.cite: self.cite = '未知' try: self.company = selector.css('.t3 .company a::text').extract()[0] #生产厂家 except IndexError as e: self.company = '未知' try: self.address = selector.css('.t3 .address::text').extract()[0] #厂家地址 except IndexError as e: self.address = '未知' try: self.license_number = selector.xpath('//ul[@class="xxs"]/li[1]/text()').extract_first().strip() #批准文号 except AttributeError: self.license_number = '未知' try: self.approval_date = selector.xpath('//ul[@class="xxs"]/li[2]/text()').extract_first().strip() #批准日期 except AttributeError: self.approval_date = '未知' try: self.form_drug = selector.xpath('//ul[@class="showlis"]/li[1]/text()').extract_first().strip() #剂型 except AttributeError: self.form_drug = '未知' try: self.spec = selector.xpath('//ul[@class="showlis"]/li[2]/text()').extract_first().strip() #规格 except AttributeError: self.spec = '未知' try: self.store = selector.xpath('//ul[@class="showlis"]/li[3]/text()').extract_first().strip().strip('。') #储存方法 except AttributeError: self.store = '未知' try: self.period_valid = selector.xpath('//ul[@class="showlis"]/li[4]/text()').extract_first().strip('。').replace('\n','') #有效期限 except AttributeError: self.period_valid = '未知' self.attention_rank = selector.css('.guanzhu cite font::text').extract_first() #关注度排名 if not self.attention_rank: self.attention_rank = '未知' self.indication = ','.join(selector.css('.whatsthis li::text').extract()) #适应症 if self.indication == '': self.indication = '未知' usage_dosage = selector.css('.ps p:nth-child(3)::text').extract_first() #用法用量 if usage_dosage: self.usage_dosage = re.sub('<.*?>','',usage_dosage).strip().replace('\n','') #禁忌症 else: self.usage_dosage = '未知' indications = selector.css('#diseaseintro::text').extract_first() #适应症概况 if indications: self.indications = re.sub('<.*?>','',indications).strip().replace('\n','') #禁忌症 else: self.indications = '未知' try: self.is_or_not_medical_insurance = selector.css('.syz_cons p:nth-child(2)::text').extract_first().split(':')[1] #是否属于医保 except AttributeError as e: self.is_or_not_medical_insurance = '未知' try: self.is_or_not_infections = selector.css('.syz_cons p:nth-child(3)::text').extract_first().split(':')[1].strip() #是否有传染性 except AttributeError as e: self.is_or_not_infections = '未知' self.related_symptoms = ','.join(selector.css('.syz_cons p:nth-child(4) a::text').extract()[:-1]) #相关症状 if len(self.related_symptoms) == 0: self.related_symptoms = '未知' self.related_examination = ','.join(selector.css('.syz_cons p:nth-child(5) a::text').extract()[:-1]) #相关检查 if len(self.related_examination) == 0: self.related_examination = '未知' def drug_instruction(self,file): """详细说明书""" html = self.read_file(file) selector = Selector(text=html) #注:不同药品之间网页结构有差别,提取的时候应注意 component = selector.xpath('//dt[text()="【成份】"]/following::*[1]').extract_first() if not component: self.component = '未知' else: self.component = re.sub('<.*?>','',component).strip() #成分 contraindication= selector.xpath('//dt[text()="【禁忌】"]/following::*[1]').extract_first() if contraindication: self.contraindication = re.sub('<.*?>','',contraindication).strip().replace('\n','') #禁忌症 else: self.contraindication = '未知' function = selector.xpath('//dt[text()="【功能主治】"]/following::*[1]').extract_first() if function: self.function = re.sub('<.*?>','',function).strip() #功能主治 else: self.function = '未知' try: self.adverse_reaction = selector.xpath('//dt[text()="【不良反应】"]/following::*[1]/p/text()').extract_first().strip('。') #不良反应 except AttributeError as e: try: self.adverse_reaction = selector.xpath('//dt[text()="【不良反应】"]/following::*[1]/text()').extract_first().strip('。') #不良反应 self.adverse_reaction = re.sub('<.*?>','',self.adverse_reaction).strip().replace('\n','') #注意事项 except AttributeError: self.adverse_reaction = '未知' attention_matters = selector.xpath('//dt[text()="【注意事项】"]/following::*[1]').extract_first() if attention_matters: self.attention_matters = re.sub('<.*?>','',attention_matters).strip().replace('\n','') #注意事项 else: self.attention_matters = '未知' self.logger.log('{}[{}]-注意事项为空'.format(self.drug_name,self.drug_id),False) try: self.interaction = selector.xpath('//dt[text()="【药物相互作用】"]/following::*[1]/p/text()').extract_first() #药物相互作用 self.interaction = re.sub('<.*?>','',self.interaction).strip().replace('\n','') #注意事项 except TypeError: self.interaction = '未知' try: self.pharmacological_action = selector.xpath('//dt[text()="【药理作用】"]/following::*[1]/p/text()').extract_first() #药理作用 self.pharmacological_action = re.sub('<.*?>','',self.pharmacological_action).strip().replace('\n','') except TypeError: self.pharmacological_action = '未知' try: self.revision_date = selector.xpath('//dt[text()="【说明书修订日期】"]/following::*[1]/text()').extract_first().strip() #说明书修订日期 except AttributeError: self.revision_date = '未知' try: self.special_population = selector.xpath('//dt[text()="【特殊人群用药】"]/following::*[1]/text()').extract_first() #特殊人群用药 self.special_population = re.sub('<.*?>','',self.special_population).strip().replace('\n','') #特殊人群用药 except TypeError: self.special_population = '未知' def drug_consultation(self,file): """用药咨询""" html = self.read_file(file) selector = Selector(text=html) drug_use_consult = selector.css('.dpzx_con .zx p::text').extract() drug_use_consult = ''.join(drug_use_consult) drug_use_consult = re.sub('<.*?>','',drug_use_consult).strip().replace('\n','') #用药咨询 self.drug_use_consult += drug_use_consult def drug_experience(self,file): """用药经验""" html = self.read_file(file) selector = Selector(text=html) drug_use_experience = selector.css('.pls_box .pls_mid p::text').extract() drug_use_experience = ''.join(drug_use_experience) drug_use_experience = re.sub('<.*?>','',drug_use_experience).strip().replace('\n','') #用药经验 self.drug_use_experience += drug_use_experience.strip()