python爬虫類のXPathとlxmlの使用

6995 ワード

一、文章の説明
本編では,lxml+XPathの組み合わせを学習中に使用したことがないため,主にlxml+XPath+pythonを学習する過程である.主にこのチュートリアルを参考にしました.
二、XPath文法規則
w 3 schoolで詳細なチュートリアルがあり、分からないところは見ることができます
三、lxml基本用法
pip install lxml
一般的に、私たちはウェブページを解析するときにこの2つの使い方だけを使えばいいです.
1、補完コード
>>> from lxml import etree
>>> text = '''

'''
>>> 
>>> html = etree.HTML(text)		#         
>>> html

>>> type(html)

>>> result = etree.tostring(html)		#    
>>> result
b'
' >>> type(result) >>> >>>

以上の結果から,lxmlは欠落したliタグを補完し,body,htmlタグも追加したことが分かる.コードをより完璧にします.
2、ファイルの読み込み
上記の読み出し文字列に加えてetreeはファイル形式を読み出し,同様の結果を得ることができる.
>>> html = etree.parse('hello.html')
>>> result = etree.tostring(html)
>>> result
>>>

四、XPathとlxmlの簡単な使用
1、liタグを取得する
>>> li = html.xpath('//li')		#  html   li  ,        
>>> li
[, , , , ]
>>> type(li)

>>>
>>>

2、すべてのliラベルの下のclass名を返す
>>> li_class = html.xpath('//li/@class')
>>> li_class
['item-0', 'item-1', 'item-inactive', 'item-1', 'item-0']
>>>

3、すべてのliラベルの下の属性名「item-0」のラベルを返す
>>> li_class_0 = html.xpath("//li[@class='item-0']")
>>> li_class_0
[, ]
>>> 

4、liタグの下のspanタグを取得する
>>> text = '''

'''
>>> html = etree.HTML(text)
>>> span = html.xpath('//li//span')
>>> span
[]
>>> span1 = html.xpath('//li/span')
>>> span1
[]
>>> 

注意:spanの前の2つの斜線は、すべてのliラベルの下に含まれるspanラベルを探し、単一の斜線は、すべてのliラベルを探しているspanというサブラベルを表します.
5、いくつ目のliラベルの下のaというサブラベルを取得する
>>> res = html.xpath('//li[last()]/a')		#    
>>> 
>>> 
>>> res = html.xpath('//li[last()-1]/a')		#     
>>> res[0].text		#  a      
'fourth item'
>>> 

6、完全に一致するか
クラス名に「external」を含める必要がありますが、後者は「external」というクラス名を必要とし、完全に一致します.
7、andおよびor演算子
もっと文法のルールはw 3 schoolを参考にして練習することができます!!!
五、小練習
XPathとBeautifulSoup,re(正規表現)で同じ内容を同時にキャプチャ
コード:
from lxml import etree
import urllib.request
from bs4 import BeautifulSoup as BS
import re


headers = {'user-agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36"}


def get_html(url):
    req = urllib.request.Request(url,headers=headers)
    response = urllib.request.urlopen(req)
    html = response.read()

    return html



def for_xpath(html):
    print('this method is for xpath...')
    result = etree.HTML(html)
    #         
    #  class   ’hot-list clearfix‘ div      a  
    hot_city = result.xpath("//div[@class='hot-list clearfix']//a")
    mdd = []
    for i in range(len(hot_city)):
        mdd.append(hot_city[i].text)

    print(mdd)
    return len(mdd)


def for_BS(html):
    print('this method is for BeautifulSoup...')
    soup = BS(html,'html.parser')
    div_col_in = soup.select('.col')[:2]    #  class col   ,    ,        
    #print(div_col_in)
    mdd = []
    for col_in in div_col_in:
        a = col_in.select('a')
        for i in range(len(a)):
            mdd.append(a[i].text)

    print(mdd)
    return len(mdd)

def for_re(html):
    print('this method is for re ...')
    mdd_all = re.findall('target="_blank">(.*?)',html)
    mdd = mdd_all[1:137]

    print(mdd)

    return len(mdd)


def main():
    url = 'http://www.mafengwo.cn/mdd/'
    html = get_html(url)
    html = html.decode('utf8')
    #print(html)
    #html1 = etree.HTML(html)
    #print(html1)
    i = for_xpath(html)
    j = for_BS(html)
    k = for_re(html)

    print('for xpath: total is %d mdd !' %i)
    print('for BS: total is %d mdd !' %j)
    print('for re: total is %d mdd !'%k)


if __name__ == '__main__':
    main()



最後に,結果は同じであり,3つの解析方式の差は多くなく,難易度は類似していることが分かった.クラス名にスペースがある場合(one-list clearfix)BeautifulSoupは取得できません???
具体的にはどの方法で実际の状况に基づいて分析したり、直接好みに惯れたりしましょう!!!