Python-選擇器Xpath,Css,Re


正則表達式(特殊字符)

 

 

chrome控制台搜索:$x('//*[@id="body_container"]/div[3]/div[2]/div/div/a[1]/@href')

^                            開頭  '^b.*'----以b開頭的任意字符
 
$                            結尾  '^b.*3$'----以b開頭,3結尾的任意字符  
 
*                            任意長度(次數),≥0
 
?                            非貪婪模式,非貪婪模式盡可能少的匹配所搜索的字符串  '.*?(b.*?b).*'----從左至右第一個b和的二個b之間的內容(包含b)
 
+                            一次或多次
 
{2}                          指定出現次數2次
 
{2,}                         出現次數≥2次
 
{2,5}                        出現次數2≤x≤5
 
|                            或   “z|food”----能匹配“z”或“food”(此處請謹慎)。“[z|f]ood”----則匹配“zood”或“food”或"zood"
 
[]                           括號中任意一個符合即可(中括號里面沒有分轉義字符)  '[abc]ooby123'----只要開頭符合[]中任意一個即可
 
[^]                          只要不出現[]的即可
 
[a-Z]                        從小a到大Z
 
.                            任意字符
 
\s                           匹配不可見字符 \n \t  '你\s好'----可以匹配‘你 好’
 
\S                           匹配可見字符,即普通字符
 
\w                           匹配下划線在內的任何單詞字符
 
\W                           和上一個相反
 
[\u4E00-\u9FA5]              只能匹配漢字
()                           要取出的信息就用括號括起來
 
\d                           數字

 尋找2個字或者3個字的XX市或者XXX區 

re.findall(re.compile('([\u4e00-\u9fa5]{2}市|[\u4e00-\u9fa5]{2}區|[\u4e00-\u9fa5]{3}市|[\u4e00-\u9fa5]{3}區)', re.S),
[\u4e00-\u9fa5]過濾中文


Xpath

article                      選取所有article元素的所有子節點
 
/article                     選取根元素article
 
article/a                    選取所有屬於article的子元素的a元素
 
//div                        選取所有div子元素(不論出現在文檔任何地方)
 
article//div                 選取所有屬於article元素的后代的div元素不管它出現在article之下的任何位置
 
//@class                     選取所有名為class的屬性
 
/article/div[1]              選取屬於srticle子元素的第一個div所有子節點
 
/article/div[last()]         選取屬於article子元素的最后一個div所有子節點
 
/article/div[last()-1]       選取屬於article子元素的倒數第二個div所有子節點
 
//div[@lang]                 選取所有擁有lang屬性的div元素
 
//div[@lang='eng']           選取所有lang屬性為eng的div元素
 
/div/*                       選取屬於div元素的所有子節點
 
//*                          選取所有元素
 
//div[@*]                    選取所有帶屬性的div元素
 
//div/a | //div/p            選取所有div元素的a個p元素
 
//span | //ul                選取文檔中的span和ul元素
 
article/div/p | //span       選取所有屬於article元素的div元素和所有的span元素

1. 取得文章標題

復制代碼
>>> title = response.xpath('//div[@class="entry-header"]/h1/text()')
>>> title
[<Selector xpath='//div[@class="entry-header"]/h1/text()' data='2016 騰訊軟件開發面試題(部分)'>]
>>> title.extract()
['2016 騰訊軟件開發面試題(部分)']
>>> title.extract()[0]
'2016 騰訊軟件開發面試題(部分)'
>>> title.extract_first()
'2016 騰訊軟件開發面試題(部分)'
復制代碼
說明
1)extract()方法會把原數據的selector類型轉變為列表類型
2)extract()會得到多個值,extract()[1]取第2個值
3)extract_first()得到第一個值,類型為字符串。extract_first(default='')如果沒取到返回默認值
 
 
2. 取得發表日期
>>> response.xpath("//p[@class='entry-meta-hide-on-mobile']/text()").extract()[0].strip().replace("·","").strip()
'2017/02/18'
 

 

3. 點贊數,span標簽里有很多class名,選一個看起來像唯一的,測試一下,然后用contains()函數簡化操作
>>> response.xpath("//span[contains(@class, 'vote-post-up')]/h10/text()").extract()
['2']
>>> response.xpath("//span[contains(@class, 'vote-post-up')]/h10/text()").extract()[0]
'2'
>>> int(response.xpath("//span[contains(@class, 'vote-post-up')]/h10/text()").extract()[0])
2

 

Xpath函數

 

 
4. 收藏數,要用正則,re模塊也是scrapy的內置模塊,注意要用非貪婪匹配,否則只會取到8
復制代碼
>>> response.xpath("//span[contains(@class, 'bookmark-btn')]/text()").extract()[0]
' 28 收藏'
>>> string = response.xpath("//span[contains(@class, 'bookmark-btn')]/text()").extract()[0]
>>> import re
>>> pattern = re.match(".*?(\d+).*", string)
>>> pattern.group(1)
'28'
復制代碼

 可以簡寫為

>>> response.xpath("//span[contains(@class, 'bookmark-btn')]/text()").re('.*?(\d+).*')
['28']
>>> response.xpath("//span[contains(@class, 'bookmark-btn')]/text()").re('.*?(\d+).*')[0]
'28'

 節點軸選擇

 

 

5. 使用列表推導式取得一個標簽中的部分元素,如下取得職場和面試字樣。適用於有些文章沒評論標簽的情況
復制代碼
找到不是以"評論"結尾的元素
>>> response.xpath("//p[@class='entry-meta-hide-on-mobile']/a/text()").extract()
['職場', ' 9 評論 ', '面試']
>>> tag_list = response.xpath("//p[@class='entry-meta-hide-on-mobile']/a/text()").extract()
>>> [element for element in tag_list if not element.strip().endswith("評論")]
['職場', '面試']
>>> tag_choose=[element for element in tag_list if not element.strip().endswith("評論")]
>>> tags=",".join(tag_choose)
>>> tags
'職場,面試'
復制代碼

 

join()函數基本語法: 'sep'.join(seq)。表示以sep為分隔符,將seq中所有的元素合並成一個新的字符串
sep表示分隔符,可以為空;
seq表示要連接的數據,數據類型可以是列表,字符串,元組或者字典
 
  • Element類型是'lxml.etree._Element',某種意義來說同時是一個列表
  • 列表的需要使用tag\attrib\text三個不同的屬性來獲取我們需要的東西
  • 變量.tag獲取到的是標簽名是---字符串
  • 變量.attrib獲取到的是節點標簽a的屬性---字典
  • 變量.text獲取到的是標簽文本--字符串  

xpath表格中取值

Ptable_items = response.xpath("//div[@class='Ptable']/div[@class='Ptable-item']/dl/dl")
        others = {}
        for item in Ptable_items:
            dt = item.xpath("./dt/text()").extract_first().strip()
            dd = item.xpath("./dd/text()").extract_first().strip()
            if "機身內存" in dt:
                if not one.get("capacity", ""):
                    one["capacity"] = dd
            elif "顏色分類" in dt:
                if not one.get("color", ""):
                    one["color"] = dd

  

Xpath string()提取多個子節點中的文本

<div> <ul class="show"> <li>275萬購昌平鄰鐵三居 總價20萬買一居</li> <li>00萬內購五環三居 140萬安家東三環</li> <li>北京首現零首付樓盤 53萬購東5環50平</li> <li>京樓盤直降5000 中信府 公園樓王現房</li> </ul> </div>

我想要把所有li標簽中的文本提取出來,並且放到一個字符串中.
在網上查了下發現使用xpath的string()函數可以實現(string()和text()的區別請自行google)
先看下常見的方法:

>>> from lxml import etree ... >>> result = html.xpath("//div/ul[@class='show']")[0] >>> result.xpath('string(.)') ' 275萬購昌平鄰鐵三居 總價20萬買一居 00萬內購五 環三居 140萬安家東三環 北京首現零首付樓盤 53萬購東5環50平 京樓盤直降5000 中信府 公園樓王現房 '

這是我查到的多數人使用的方法,還有人使用了concat()函數,更麻煩就不提了.
但是上面的匹配明顯感覺可以寫到一條xpath里面的,為什么非要分開寫!忍不住吐槽一下


xpath string()函數的調用寫法:

>>> html.xpath("string(//div/ul[@class='show'])") ' 275萬購昌平鄰鐵三居 總價20萬買一居 00萬內購五 環三居 140萬安家東三環 北京首現零首付樓盤 53萬購東5環50平 京樓盤直降5000 中信府 公園樓王現房 '

再吐槽下上面那種寫法.在xpath語法里面,點(.)表示當前節點,當前節點不就是html.xpath("//div/ul[@class='show']")[0]取到的節點元素嗎!!!

Css

*                            選取所有節點
 
#container                   選取id為container的節點
 
.container                   選取所有class包含container的節點
 
li a                         選取所有li下的所有a節點
 
ul+p                         選取ul后面的第一個p元素
 
div#container > ul           選取id為container的div的第一個ul子元素
 
ul ~ p                       選取與ul相鄰的所有p元素
 
a[title]                     選取所有有title屬性的a元素
 
a[href="http://jobbole.com"] 選取所有href屬性為jobbole.com
 
a[href*="jobole"]            選取所有href屬性包含jobbole的a元素
 
a[href^="http"]              選取所有href屬性值以http開頭的a元素
 
a[href$=".jpg"]              選取所有href屬性值以.jpg結尾的a元素
 
input[type=radio]:checked    選取選中的radio的元素
 
div:not(#container)          選取所有id非container的div元素
 
li:nth-child(3)              選取第三個li元素
 
tr:nth-child(2n)             第偶數個tr元素

  

^                            開頭   '^b.*' - - - - 以b開頭的任意字符
 
$                            結尾   '^b.*3$' - - - - 以b開頭, 3 結尾的任意字符  
 
*                             任意長度(次數),≥ 0
 
?                            非貪婪模式,非貪婪模式盡可能少的匹配所搜索的字符串   '.*?(b.*?b).*' - - - - 從左至右第一個b和的二個b之間的內容(包含b)
 
+                             一次或多次
 
{ 2 }                          指定出現次數 2
 
{ 2 ,}                         出現次數≥ 2
 
{ 2 , 5 }                        出現次數 2 ≤x≤ 5
 
|                            或   “z|food” - - - - 能匹配“z”或“food”(此處請謹慎)。“[z|f]ood” - - - - 則匹配“zood”或“food”或 "zood"
 
[]                           括號中任意一個符合即可(中括號里面沒有分轉義字符)   '[abc]ooby123' - - - - 只要開頭符合[]中任意一個即可
 
[^]                          只要不出現[]的即可
 
[a - Z]                        從小a到大Z
 
.                            任意字符
 
\s                           匹配不可見字符 \n \t   '你\s好' - - - - 可以匹配‘你 好’
 
\S                           匹配可見字符,即普通字符
 
\w                           匹配下划線在內的任何單詞字符
 
\W                           和上一個相反
 
[\u4E00 - \u9FA5]              只能匹配漢字
()                           要取出的信息就用括號括起來
 
\d                           數字


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM