Python爬蟲數據提取總結


第一種 : 正則表達式

  1. 正則表達式是 對於it來說最常用的一個,就是用事先定義好的一些特定的字符,及這些特定的組合,組成一個"規則字符串",
  2. 規則
模式 描述
^ 匹配字符串的開頭
$ 匹配字符串的末尾
. 匹配任意字符,除了換行符,當re.DOTALL標記被指定時,則可以匹配包括換行符的任意字符
[…] 用來表示一組字符,單獨列出:[amk] 匹配 ‘a’,‘m’或’k’
[^…] 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符
re* 匹配0個或多個的表達式
re+ 匹配1個或多個的表達式
re? 匹配0個或1個由前面的正則表達式定義的片段,非貪婪方式
re{ n}
re{ n,} 精確匹配n個前面表達式
re{ n, m} 匹配 n 到 m 次由前面的正則表達式定義的片段,貪婪方式
a b
(re) G匹配括號內的表達式,也表示一個組
(?imx) 正則表達式包含三種可選標志:i, m, 或 x 。只影響括號中的區域
(?-imx) 正則表達式關閉 i, m, 或 x 可選標志。只影響括號中的區域
(?: re) 類似 (…), 但是不表示一個組
(?imx: re) 在括號中使用i, m, 或 x 可選標志
(?-imx: re) 在括號中不使用i, m, 或 x 可選標志
(?#…) 注釋
(?= re) 前向肯定界定符。如果所含正則表達式,以 … 表示,在當前位置成功匹配時成功,否則失敗。但一旦所含表達式已經嘗試,匹配引擎根本沒有提高;模式的剩余部分還要嘗試界定符的右邊。
(?! re) 前向否定界定符。與肯定界定符相反;當所含表達式不能在字符串當前位置匹配時成功
(?> re) 匹配的獨立模式,省去回溯
\w 匹配字母數字及下划線
\W 匹配非字母數字及下划線
\s 匹配任意空白字符,等價於 [\t\n\r\f].
\S 匹配任意非空字符
\d 匹配任意數字,等價於 [0-9]
\D 匹配任意非數字
\A 匹配字符串開始
\Z 匹配字符串結束,如果是存在換行,只匹配到換行前的結束字符串。c
\z 匹配字符串結束
\G 匹配最后匹配完成的位置
\b 匹配一個單詞邊界,也就是指單詞和空格間的位置。例如, ‘er\b’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’
\B 匹配非單詞邊界。‘er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’
\n, \t, 等. 匹配一個換行符。匹配一個制表符。等
\1…\9 匹配第n個分組的內容
\10 匹配第n個分組的內容,如果它經匹配。否則指的是八進制字符碼的表達式
[\u4e00-\u9fa5] 中文

2. 正則表達式相關注解

2.1 數量詞的貪婪模式與非貪婪模式

正則表達式通常用於在文本中查找匹配的字符串
Python里數量詞默認是貪婪的(在少數語言里也可能是默認非貪婪),總是嘗試匹配盡可能多的字符;非貪婪的則相反,總是嘗試匹配盡可能少的字符

例如:正則表達式”ab*”如果用於查找”abbbc”,將找到”abbb”。而如果使用非貪婪的數量詞”ab*?”,將找到”a”

2.2 常用方法

  • re.match
    • re.match 嘗試從字符串的起始位置匹配一個模式,如果不是起始位置匹配成功的話,match()就返回none
    • 函數語法:
      re.match(pattern, string, flags=0)
  • re.search
    • re.search 掃描整個字符串並返回第一個成功的匹配。
    • 函數語法:
      re.search(pattern, string, flags=0)
  • re.sub
    • re.sub 替換字符串
      re.sub(pattern,replace,string)
  • re.findall
    • re.findall 查找全部
      re.findall(pattern,string,flags=0)

第二種:bs4 的使用

  1. bs4 就是Beautiful Soup 的簡稱,這是一個工具箱,通過解析文檔為用戶提供需要抓取的數據,
  2. 使用這個不需要在編碼的上面考慮,他會自動轉換為utf-8編碼。
  3. 但是使用這個的前提的就是網頁是完整的,但是現在的網頁大多規范化,所以都是可以用的
  4. 官網: http://beautifulsoup.readthedocs.io/zh_CN/latest/
  5. bs4 必須使用一種解析器,如果你沒有安裝其他的HTML解析器,他會默認使用自帶的解析器,但是lxml 解析器更加強大,速度更快,推薦安裝
  6. 對於 四種解析器的對比
解析器 使用方法 優勢 劣勢
Python標准庫 BeautifulSoup(markup, “html.parser”) 1. Python的內置標准庫 2. 執行速度適中 3.文檔容錯能力強 Python 2.7.3 or 3.2.2)前 的版本中文檔容錯能力差
lxml HTML 解析器 BeautifulSoup(markup, “lxml”) 1. 速度快 2.文檔容錯能力強 需要安裝C語言庫
lxml XML 解析器 BeautifulSoup(markup, [“lxml”, “xml”]) BeautifulSoup(markup, “xml”) 1. 速度快 2.唯一支持XML的解析器 3.需要安裝C語言庫
html5lib BeautifulSoup(markup, “html5lib”) 1. 最好的容錯性 2.以瀏覽器的方式解析文檔 3.生成HTML5格式的文檔 4.速度慢 不依賴外部擴展
  1. 對於bs4 有四大對象種類
    1. Tag
    2. navigableString
    3. BeautifulSoup
    4. Comment
  2. 更加細致的編寫的方法,可以去官網查看

第三種 : Xpath

  1. 相對於其他的方法,我更加的喜歡這種方法,因為更加的方便

  2. 官網 : http://lxml.de/index.html

  3. w3c :http://www.w3school.com.cn/xpath/index.asp

  4. xpath 是一門在XML文檔中查找信息的語言,

  5. 是以節點來表達關系的

    • 父(Parent)
    • 子(Children)
    • 同胞(Sibling)
    • 先輩(Ancestor)
    • 后代(Descendant)
  6. 選取節點

    1. 常用的路徑表達式
表達式 描述
nodename 選取此節點的所有子節點
/ 從根節點選取
// 從匹配選擇的當前節點選擇文檔中的節點,而不考慮它們的位置
. 選取當前節點
選取當前節點的父節點
@ 選取屬性
  1. 通配符

XPath 通配符可用來選取未知的 XML 元素。

通配符 描述 舉例 結果
* 匹配任何元素節點 xpath(‘div/*’) 獲取div下的所有子節點
@* 匹配任何屬性節點 xpath(‘div[@*]’) 選取所有帶屬性的div節點
node() 匹配任何類型的節點
  1. 選取若干路徑

通過在路徑表達式中使用“|”運算符,您可以選取若干個路徑

表達式 結果
xpath(’//div|//table’) 獲取所有的div與table節點
  1. 謂語

謂語被嵌在方括號內,用來查找某個特定的節點或包含某個制定的值的節點

表達式 結果
xpath(’/body/div[1]’) 選取body下的第一個div節點
xpath(’/body/div[last()]’) 選取body下最后一個div節點
xpath(’/body/div[last()-1]’) 選取body下倒數第二個節點
xpath(’/body/div[positon()< 3]’) 選取body下前個div節點
xpath(’/body/div[@class]’) 選取body下帶有class屬性的div節點
xpath(’/body/div[@class=“main”]’) 選取body下class屬性為main的div節點
xpath(’/body/div[price>35.00]’) 選取body下price元素大於35的div節點

第四種 : jsonPath

這個是Python自帶的輕量級的數據交換格式,這個與XML相較比不相上下

3.1 json.loads()

  1. Python中的json 模塊
    - 提供了四個功能 : dumps,dump,loads,load 用於字符串和Python數據類型進行轉換

把Json格式字符串解碼轉換成Python對象 從json到python的類型轉化對照如下:

import json

strList = '[1, 2, 3, 4]'
strDict = '{"city": "北京", "name": "范爺"}'
json.loads(strList) 
# [1, 2, 3, 4]
json.loads(strDict) # json數據自動按Unicode存儲
# {u'city': u'\u5317\u4eac', u'name': u'\u5927\u732b'}

3.2 json.dumps()

實現python類型轉化為json字符串,返回一個str對象 把一個Python對象編碼轉換成Json字符串

從python原始類型向json類型的轉化對照如下:

# json_dumps.py

import json


listStr = [1, 2, 3, 4]
tupleStr = (1, 2, 3, 4)
dictStr = {"city": "北京", "name": "范爺"}

json.dumps(listStr)
# '[1, 2, 3, 4]'
json.dumps(tupleStr)
# '[1, 2, 3, 4]'

# 注意:json.dumps() 序列化時默認使用的ascii編碼
# 添加參數 ensure_ascii=False 禁用ascii編碼,按utf-8編碼

json.dumps(dictStr) 
# '{"city": "\\u5317\\u4eac", "name": "\\u5927\\u5218"}'

print(json.dumps(dictStr, ensure_ascii=False))
# {"city": "北京", "name": "范爺"}

3.3 json.dump()

將Python內置類型序列化為json對象后寫入文件

import json

listStr = [{"city": "北京"}, {"name": "范爺"}]
json.dump(listStr, open("listStr.json","w"), ensure_ascii=False)

dictStr = {"city": "北京", "name": "范爺"}
json.dump(dictStr, open("dictStr.json","w"), ensure_ascii=False)

使用這個的好處

  1. 如果網頁是用ajax來進行 數據交互的,

  2. 使用jsonPath 就是可以直接使用url 來進行獲取數據,相對於其他就更加的方便

  3. 示例

from urllib.request import urlopen
from urllib.request import Request
import jsonpath
import json


url = 'http://www.lagou.com/lbs/getAllCitySearchLabels.json'
request =Request(url)
response = urlopen(request)
html = response.read()
# 把json格式字符串轉換成python對象
jsonobj = json.loads(html)
# 從根節點開始,匹配name節點
citylist = jsonpath.jsonpath(jsonobj,'$..name')
print(citylist)
print(type(citylist))
fp = open('city.json','w')
content = json.dumps(citylist, ensure_ascii=False)
print(content)
fp.write(content)
fp.close()


免責聲明!

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



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