爬蟲之數據解析的三種方式

一,正則表達式解析

re正則就不寫了,前面已經寫入一篇很詳細的正則表達式模塊了~

而且,在爬蟲中,下面兩種方式用的多一些~

正則表達式:https://www.cnblogs.com/peng104/p/9619801.html

大致用法:

pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?src="(.*?)".*?name"><a'+'.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>'+'.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>', re.S)
items = re.findall(pattern, html)

二,Xpath解析

簡介及安裝

簡介:XPath 是一門在 XML 文檔中查找信息的語言。XPath 可用來在 XML 文檔中對元素和屬性進行遍歷。XPath 是 W3C XSLT 標準的主要元素,并且 XQuery 和 XPointer 都構建于 XPath 表達之上。

安裝:pip install lxml

調用方法:

# 先導包
from lxml import etree# 將html文檔或者xml文檔轉換成一個etree對象,然后調用對象中的方法查找指定的節點
# 1. 本地文件
tree = etree.parse(文件名)
tree.xpath("xpath表達式")# 2. 網絡數據
tree = etree.HTML(網頁內容字符串)
tree.xpath("xpath表達式")

語法簡介

先準備一個HTML格式的字符串

html_doc = """
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><div class="d1"><div class="d2"><p class="story"><a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and<a href="http://example.com/tillie" id="link3">Tillie</a></p></div><div><p id="p1">人生苦短</p><p id="p2">我用python</p></div>
</div><div class="d3"><a href="http://www.baidu.com">baidu</a><p>百度</p>
</div></body>
</html>
"""
變量準備

1,選取節點

nodename     # 選取nodename節點的所有子節點         xpath(‘//div’)         # 選取了所有div節點
/            # 從根節點選取                        xpath(‘/div’)          # 從根節點上選取div節點
//           # 選取所有的當前節點,不考慮他們的位置    xpath(‘//div’)         # 選取所有的div節點
.            # 選取當前節點                        xpath(‘./div’)         # 選取當前節點下的div節點
..           # 選取當前節點的父節點                 xpath(‘..’)            # 回到上一個節點
@            # 選取屬性                           xpath(’//@calss’)     # 選取所有的class屬性#######################?例子?######################

ret=selector.xpath("//div")
ret=selector.xpath("/div")
ret=selector.xpath("./div")
ret=selector.xpath("//p[@id='p1']")
ret=selector.xpath("//div[@class='d1']/div/p[@class='story']")

2,謂語

表達式                                         結果
xpath(‘/body/div[1]’)                     # 選取body下的第一個div節點
xpath(‘/body/div[last()]’)                # 選取body下最后一個div節點
xpath(‘/body/div[last()-1]’)              # 選取body下倒數第二個div節點
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節點#######################?例子?######################

ret=selector.xpath("//p[@class='story']//a[2]")
ret=selector.xpath("//p[@class='story']//a[last()]")

3,通配符

Xpath通過通配符來選取未知的XML元素

表達式                 結果
xpath(’/div/*’)     # 選取div下的所有子節點
xpath(‘/div[@*]’)    # 選取所有帶屬性的div節點#######################?例子?######################

ret=selector.xpath("//p[@class='story']/*")
ret=selector.xpath("//p[@class='story']/a[@class]")

4,取多個路徑

使用 “|” 運算符可以選取多個路徑

表達式                         結果
xpath(‘//div|//table’)    # 選取所有的div和table節點#######################?例子?######################

ret=selector.xpath("//p[@class='story']/a[@class]|//div[@class='d3']")
print(ret)

5,Xpath軸

軸可以定義相對于當前節點的節點集

軸名稱                      表達式                                  描述
ancestor                xpath(‘./ancestor::*’)              # 選取當前節點的所有先輩節點(父、祖父)
ancestor-or-self        xpath(‘./ancestor-or-self::*’)      # 選取當前節點的所有先輩節點以及節點本身
attribute               xpath(‘./attribute::*’)             # 選取當前節點的所有屬性
child                   xpath(‘./child::*’)                 # 返回當前節點的所有子節點
descendant              xpath(‘./descendant::*’)            # 返回當前節點的所有后代節點(子節點、孫節點)
following               xpath(‘./following::*’)             # 選取文檔中當前節點結束標簽后的所有節點
following-sibing        xpath(‘./following-sibing::*’)      # 選取當前節點之后的兄弟節點
parent                  xpath(‘./parent::*’)                # 選取當前節點的父節點
preceding               xpath(‘./preceding::*’)             # 選取文檔中當前節點開始標簽前的所有節點
preceding-sibling       xpath(‘./preceding-sibling::*’)     # 選取當前節點之前的兄弟節點
self                    xpath(‘./self::*’)                  # 選取當前節點

6,功能函數

使用功能函數能夠更好的進行模糊搜索

函數                  用法                                                               解釋
starts-with         xpath(‘//div[starts-with(@id,”ma”)]‘)                        # 選取id值以ma開頭的div節點
contains            xpath(‘//div[contains(@id,”ma”)]‘)                           # 選取id值包含ma的div節點
and                 xpath(‘//div[contains(@id,”ma”) and contains(@id,”in”)]‘)    # 選取id值包含ma和in的div節點
text()              xpath(‘//div[contains(text(),”ma”)]‘)                        # 選取節點文本包含ma的div節點

Element對象

from lxml.etree import _Element
for obj in ret:print(obj)print(type(obj))  # from lxml.etree import _Element'''
Element對象class xml.etree.ElementTree.Element(tag, attrib={}, **extra)tag:string,元素代表的數據種類。text:string,元素的內容。tail:string,元素的尾形。attrib:dictionary,元素的屬性字典。#針對屬性的操作clear():清空元素的后代、屬性、text和tail也設置為None。get(key, default=None):獲取key對應的屬性值,如該屬性不存在則返回default值。items():根據屬性字典返回一個列表,列表元素為(key, value)。keys():返回包含所有元素屬性鍵的列表。set(key, value):設置新的屬性鍵與值。#針對后代的操作append(subelement):添加直系子元素。extend(subelements):增加一串元素對象作為子元素。#python2.7新特性find(match):尋找第一個匹配子元素,匹配對象可以為tag或path。findall(match):尋找所有匹配子元素,匹配對象可以為tag或path。findtext(match):尋找第一個匹配子元素,返回其text值。匹配對象可以為tag或path。insert(index, element):在指定位置插入子元素。iter(tag=None):生成遍歷當前元素所有后代或者給定tag的后代的迭代器。#python2.7新特性iterfind(match):根據tag或path查找所有的后代。itertext():遍歷所有后代并返回text值。remove(subelement):刪除子元素。
'''

三,BeautifulSoup

簡介及安裝

簡介:

? ? Beautiful Soup提供一些簡單的、python式的函數用來處理導航、搜索、修改分析樹等功能。
? ? 它是一個工具箱,通過解析文檔為用戶提供需要抓取的數據,因為簡單,所以不需要多少代碼就可以寫出一個完整的應用程序。

安裝:pip3 install beautifulsoup4

解析器:

? ??Beautiful Soup支持Python標準庫中的HTML解析器,還支持一些第三方的解析器,如果我們不安裝它,則 Python 會使用 Python默認的解析器,lxml 解析器更加強大,速度更快

官方文檔

簡單使用

使用方式:可以將一個html文檔,轉化為BeautifulSoup對象,然后通過對象的方法或者屬性去查找指定的節點內容

from bs4 import BeautifulSoup# 轉化本地文件
soup = BeautifulSoup(open('本地文件'), 'lxml')# 轉化網絡文件
soup = BeautifulSoup('字符串類型或者字節類型', 'lxml')# 從文檔中獲取所有文字內容:
print(soup.get_text())

語法簡介

# 1.根據標簽名查找- soup.a   只能找到第一個符合要求的標簽
# 2.獲取屬性- soup.a.attrs  獲取a所有的屬性和屬性值,返回一個字典- soup.a.attrs['href']   獲取href屬性- soup.a['href']   也可簡寫為這種形式
# 3.獲取內容- soup.a.string- soup.a.text- soup.a.get_text()注意:如果標簽還有標簽,那么string獲取到的結果為None,而其它兩個,可以獲取文本內容
# 4.find:找到第一個符合要求的標簽- soup.find('a')  找到第一個符合要求的- soup.find('a', title="xxx")- soup.find('a', alt="xxx")- soup.find('a', class_="xxx")- soup.find('a', id="xxx")
# 5.find_all:找到所有符合要求的標簽- soup.find_all('a')- soup.find_all(['a','b']) 找到所有的a和b標簽- soup.find_all('a', limit=2)  限制前兩個
# 6.根據選擇器選擇指定的內容select:soup.select('#feng')- 常見的選擇器:標簽選擇器(a)、類選擇器(.)、id選擇器(#)、層級選擇器- 層級選擇器:div .dudu #lala .meme .xixi  下面好多級div > p > a > .lala          只能是下面一級注意:select選擇器返回永遠是列表,需要通過下標提取指定的對象

find_all()

先準備一個HTML格式的字符串

html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p id="my p" class="title"><b id="bbb" class="boldest">The Dormouse's story</b>
</p><p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p><p class="story">...</p>
"""
變量準備

1,五種過濾器

字符串、正則表達式、列表、True、方法

from bs4 import BeautifulSoup
soup=BeautifulSoup(html_doc,'lxml')#1、字符串:即標簽名
print(soup.find_all('b'))#2、正則表達式
import re
print(soup.find_all(re.compile('^b'))) #找出b開頭的標簽,結果有body和b標簽#3、列表:如果傳入列表參數,Beautiful Soup會將與列表中任一元素匹配的內容返回.下面代碼找到文檔中所有<a>標簽和<b>標簽:
print(soup.find_all(['a','b']))#4、True:可以匹配任何值,下面代碼查找到所有的tag,但是不會返回字符串節點
print(soup.find_all(True))
for tag in soup.find_all(True):print(tag.name)#5、方法:如果沒有合適過濾器,那么還可以定義一個方法,方法只接受一個元素參數 ,如果這個方法返回 True 表示當前元素匹配并且被找到,如果不是則反回 False
def has_class_but_no_id(tag):return tag.has_attr('class') and not tag.has_attr('id')
print(soup.find_all(has_class_but_no_id))

2、按照類名查找

注意:關鍵字是class_,class_=value,value可以是五種選擇器之一

print(soup.find_all('a',class_='sister')) # 查找類為sister的a標簽
print(soup.find_all('a',class_='sister ssss')) # 查找類為sister和sss的a標簽,順序錯誤也匹配不成功
print(soup.find_all(class_=re.compile('^sis'))) # 查找類為sister的所有標簽

3、attrs

print(soup.find_all('p',attrs={'class':'story'}))

4、text

值可以是:字符,列表,True,正則

print(soup.find_all(text='Elsie'))
print(soup.find_all('a',text='Elsie'))

5、limit參數

如果文檔樹很大那么搜索會很慢.如果我們不需要全部結果,可以使用 limit 參數限制返回結果的數量.效果與SQL中的limit關鍵字類似,當搜索到的結果數量達到 limit 的限制時,就停止搜索返回結果

print(soup.find_all('a',limit=2))

6、recursive

調用tag的 find_all() 方法時,Beautiful Soup會檢索當前tag的所有子孫節點,如果只想搜索tag的直接子節點,可以使用參數 recursive=False .

print(soup.html.find_all('a'))
print(soup.html.find_all('a',recursive=False))

tag

像調用 find_all() 一樣調用tag find_all() 幾乎是Beautiful Soup中最常用的搜索方法,所以我們定義了它的簡寫方法. BeautifulSoup 對象和 tag 對象可以被當作一個方法來使用~

這個方法的執行結果與調用這個對象的 find_all() 方法相同~

# 下面兩行代碼是等價的:
soup.find_all("a")
soup("a")# 這兩行代碼也是等價的:
soup.title.find_all(text=True)
soup.title(text=True)

find

find( name , attrs , recursive , text , **kwargs )

find_all() 方法將返回文檔中符合條件的所有tag,盡管有時候我們只想得到一個結果.比如文檔中只有一個<body>標簽,那么使用 find_all() 方法來查找<body>標簽就不太合適, 使用 find_all 方法并設置 limit=1 參數不如直接使用 find() 方法

下面兩行代碼是等價的:soup.find_all('title', limit=1)
# [<title>The Dormouse's story</title>]
soup.find('title')
# <title>The Dormouse's story</title>

唯一的區別是 find_all() 方法的返回結果是值包含一個元素的列表,而 find() 方法直接返回結果.
find_all() 方法沒有找到目標是返回空列表, find() 方法找不到目標時,返回 None .

print(soup.find("nosuchtag"))
# None

soup.head.title 是 tag的名字 方法的簡寫.這個簡寫的原理就是多次調用當前tag的 find() 方法:

soup.head.title
# <title>The Dormouse's story</title>
soup.find("head").find("title")
# <title>The Dormouse's story</title>

?

轉載于:https://www.cnblogs.com/peng104/p/10317601.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/388409.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/388409.shtml
英文地址,請注明出處:http://en.pswp.cn/news/388409.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

相對于硬件計算機軟件就是,計算機的軟件是將解決問題的方法,軟件是相對于硬件來說的...

計算機網絡管理軟件是為計算機網絡配置的系統軟件。它負責對網絡資源進行組織和管理&#xff0c;實現相互之間的通信。計算機網絡管理軟件包括網絡操作系統和數據通信處理程序。前者用于協調網絡中各計算機的操作系統及實現網絡資源的傳遞&#xff0c;后者用于網絡內的通信&…

數據冒險控制冒險_勞動生產率和其他冒險

數據冒險控制冒險Labor productivity is considered one of the most important indicators of a country’s well-being. However, we don’t know so much about it, let’s try to figure out how it is calculated, and how things are with it in the world (data source:…

如何把一個java程序打包成exe文件,運行在沒有java虛

如何把一個java程序打包成exe文件&#xff0c;運行在沒有java虛 核心提示&#xff1a;首先&#xff0c;將編譯好的程序打包成jar文件&#xff0c;然后做出exe&#xff0c;這樣代碼就不可見了&#xff1b;但是exe文件在沒有安裝jre的電腦上不能運行&#xff0c;如果要求客戶再去…

Java后端WebSocket的Tomcat實現

原文&#xff1a;https://www.cnblogs.com/xdp-gacl/p/5193279.html 一.WebSocket簡單介紹 隨著互聯網的發展&#xff0c;傳統的HTTP協議已經很難滿足Web應用日益復雜的需求了。近年來&#xff0c;隨著HTML5的誕生&#xff0c;WebSocket協議被提出&#xff0c;它實現了瀏覽器與…

加速業務交付,從 GKE 上使用 Kubernetes 和 Istio 開始

原文來源于&#xff1a;谷歌云技術博客 許多企業機構正在把全部或部分 IT 業務遷移到云端&#xff0c;幫助企業更好的運營。不過這樣的大規模遷移&#xff0c;在企業的實際操作中也有一定難度。不少企業保存在本地服務器的重要資源&#xff0c;并不支持直接遷移到云端。 另外&a…

knn 鄰居數量k的選取_選擇K個最近的鄰居

knn 鄰居數量k的選取Classification is more-or-less just a matter of figuring out to what available group something belongs.分類或多或少只是弄清楚某個事物所屬的可用組的問題。 Is Old Town Road a rap song or a country song?Old Town Road是說唱歌曲還是鄉村歌曲…

計算機網絡中 子網掩碼的算法,[網絡天地]子網掩碼快速算法(轉載)

看到一篇很好的資料&#xff0c;大家分享有很多人肯定對設定子網掩碼這個不熟悉&#xff0c;很頭疼&#xff0c;那么我現在就告訴大家一個很容易算子網掩碼的方法&#xff0c;幫助一下喜歡偷懶的人&#xff1a;)大家都應該知道2的0次方到10次方是多少把&#xff1f;也給大家說一…

EXTJS+JSP上傳文件帶進度條

需求來源是這樣的&#xff1a;上傳一個很大的excel文件到server&#xff0c; server會解析這個excel&#xff0c; 然后一條一條的插入到數據庫&#xff0c;整個過程要耗費很長時間&#xff0c;因此當用戶點擊上傳之后&#xff0c;需要顯示一個進度條&#xff0c;并且能夠根據后…

android Json詳解

Json:一種輕量級的數據交換格式&#xff0c;具有良好的可讀和便于快速編寫的特性。業內主流技術為其提供了完整的解決方案&#xff08;有點類似于正則表達式 &#xff0c;獲得了當今大部分語言的支持&#xff09;&#xff0c;從而可以在不同平臺間進行數據交換。JSON采用兼容性…

react實踐

React 最佳實踐一、 React 與 AJAXReact 只負責處理 View 這一層&#xff0c;它本身不涉及網絡請求 /AJAX: 第一&#xff0c;用什么技術從服務端獲取數據&#xff1b; 第二&#xff0c;獲取到的數據應該放在 react 組件的什么位置。 事實上是有很多的&#xff1a;fetch()、fetc…

什么樣的代碼是好代碼_什么是好代碼?

什么樣的代碼是好代碼編碼最佳實踐 (Coding Best-Practices) In the following section, I will introduce the topic at hand, giving you a sense of what this post will cover, and how each argument therein will be approached. Hopefully, this will help you decide w…

nginx比較apache

話說nginx在大壓力的環境中比apache的表現要好&#xff0c;于是下載了一個來折騰一下。 下載并編譯安裝&#xff0c;我的編譯過程有點特別&#xff1a; 1。去除調試信息&#xff0c;修改$nginx_setup_path/auto/cc/gcc這個文件&#xff0c;將 CFLAGS"$CFLAGS -g" …

計算機主板各模塊復位,電腦主板復位電路工作原理分析

電源、時鐘、復位是主板能正常工作的三大要素。主板在電源、時鐘都正常后&#xff0c;復位系統發出復位信號&#xff0c;主板各個部件在收到復位信號后&#xff0c;同步進入初始化狀態。如圖7-11所示為復位電路的工作原理圖&#xff0c;各個十板實現復位的電路不盡相同&#xf…

Docker制作dotnet core控制臺程序鏡像

(1)首先我們到某個目錄下&#xff0c;然后在此目錄下打開visual studio code. 2.編輯docker file文件如下: 3.使用dotnet new console創建控制臺程序; 4.使用docker build -t daniel/console:dev .來進行打包; 5.啟動并運行鏡像; 6.我們可以看到打包完的鏡像將近2G,因為我們使用…

【362】python 正則表達式

參考&#xff1a;正則表達式 - 廖雪峰 參考&#xff1a;Python3 正則表達式 - 菜鳥教程 參考&#xff1a;正則表達式 - 教程 re.match 嘗試從字符串的起始位置匹配一個模式&#xff0c;如果不是起始位置匹配成功的話&#xff0c;match()就返回none。 re.search 掃描整個字符串并…

在Python中使用Twitter Rest API批量搜索和下載推文

數據挖掘 &#xff0c; 編程 (Data Mining, Programming) Getting Twitter data獲取Twitter數據 Let’s use the Tweepy package in python instead of handling the Twitter API directly. The two things we will do with the package are, authorize ourselves to use the …

第一套數字電子計算機,計算機試題第一套

《計算機試題第一套》由會員分享&#xff0c;可在線閱讀&#xff0c;更多相關《計算機試題第一套(5頁珍藏版)》請在人人文庫網上搜索。1、計算機試題第一套1、計算機之所以能自動運算,就是由于采用了工作原理。A、布爾邏輯。B 儲存程序。C、數字電路。D,集成電路答案選B2、“長…

Windows7 + Nginx + Memcached + Tomcat 集群 session 共享

一&#xff0c;環境說明 操作系統是Windows7家庭版&#xff08;有點不專業哦&#xff0c;呵呵&#xff01;&#xff09;&#xff0c;JDK是1.6的版本&#xff0c; Tomcat是apache-tomcat-6.0.35-windows-x86&#xff0c;下載鏈接&#xff1a;http://tomcat.apache.org/ Nginx…

git 版本控制(一)

新建代碼庫repository 1、在當前目錄新建一個git代碼庫 git init git init projectname 2、下載一個項目&#xff0c;如果已經有了遠端的代碼&#xff0c;則可以使用clone下載 git clone url 增加/刪除/改名文件 1、添加指定文件到暫存區 git add filename 2、添加指定目錄到暫…

rollup學習小記

周末在家重構網關的Npm包&#xff0c;用到了rollup&#xff0c;記下筆記 rollup適合庫library的開發&#xff0c;而webpack適合應用程序的開發。 rollup也支持tree-shaking&#xff0c;自帶的功能。 package.json 也具有 module 字段&#xff0c;像 Rollup 和 webpack 2 這樣的…