zoukankan      html  css  js  c++  java
  • 爬虫解析之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('
    ','')   #有效期限
            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('
    ','')  #禁忌症
            else:
                self.usage_dosage = '未知'
            indications = selector.css('#diseaseintro::text').extract_first()  #适应症概况
            if indications:
                self.indications = re.sub('<.*?>','',indications).strip().replace('
    ','')  #禁忌症
            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('
    ','')  #禁忌症
            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('
    ','')  #注意事项
                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('
    ','')  #注意事项
            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('
    ','')  #注意事项
            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('
    ','')
            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('
    ','')  #特殊人群用药
            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('
    ','')  #用药咨询
            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('
    ','')  #用药经验
            self.drug_use_experience += drug_use_experience.strip()
    View Code

       xapth的高级用法

  • 相关阅读:
    caffe绘制训练过程的loss和accuracy曲线
    ROC曲线和PR曲线
    Lintcode--009(单词切分)
    已知有字符串foo=”get-element-by-id”,写一个function将其转化成驼峰表示法”getElementById”
    web前端性能优化汇总
    Restful风格的前后端分离
    渐进式 JPEG (Progressive JPEG)来提升用户体验
    ESLint检测JavaScript代码
    JavaScript对象浅复制
    JavaScript对象深复制
  • 原文地址:https://www.cnblogs.com/zhangyafei/p/9947756.html
Copyright © 2011-2022 走看看