Python-選擇器Xpath,Css,Re

正則表達式(特殊字符)

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

^                            開頭  '^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區 python

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'
複製代碼

 能夠簡寫爲chrome

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

 節點軸選擇scrapy

 

 

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)
先看下常見的方法:ide

>>> 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]取到的節點元素嗎!!!post

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                           數字
相關文章
相關標籤/搜索