網路爬蟲大型教程(二)
網路爬蟲(二)
一 基礎爬取
1. 獲取網頁內容
urllib是Python的標準庫,包含了從網路請求資料,處理cookie,甚至改變像請求頭和使用者代理這些後設資料的函式
from urllib.request import urlopen
html = urlopen("http://pythonscraping.com/pages/page1.html")
print(html.read())
2. Beautifulsoup
通過定位 HTML 標籤來格式化和組織複雜的網路資訊,用簡單易用的 Python 物件為我們展現 XML 結構資訊。
安裝初步常用包
$pip install bs4
$pip install requests
$pip install lxml
3.第一個例子
from urllib.request import urlopen
from bs4 import BeautifulSoup
html = urlopen("http://www.pythonscraping.com/pages/page1.html")
bsObj = BeautifulSoup(html.read(),"html.parser")
print(bsObj.h1)
匯入 urlopen,然後呼叫 html.read() 獲取網頁的 HTML 內容。這樣就可以把 HTML 內容傳到 BeautifulSoup 物件,轉換成下面的結構 :
html → <html><head>...</head><body>...</body></html>
— head → <head><title>A Useful Page<title></head>
— title → <title>A Useful Page</title>
— body → <body><h1>An Int...</h1><div>Lorem ip...</div></body>
— h1 → <h1>An Interesting Title</h1>
— div → <div>Lorem Ipsum dolor...</div>
從網頁中提取的 h1 標籤被嵌在 BeautifulSoup 物件 bsObj 結構的第二層
(html → body → h1)。不過從物件裡提取 h1 標籤的時候,可以直接呼叫它:
bsObj.h1
下面這些函式呼叫都可以達到同樣的效果。
bsObj.html.body.h1
bsObj.body.h1
bsObj.html.h1
4.異常處理
try:
html = urlopen("http://www.pythonscraping.com/pages/page1.html")
except HTTPError as e:
print(e)
# 返回空值,中斷程式,或者執行另一個方案
else:
# 程式繼續。注意:如果你已經在上面異常捕捉那一段程式碼裡返回或中斷(break),
# 那麼就不需要使用else語句了,這段程式碼也不會執行
當自己呼叫標籤不存在,也會導致錯誤的發生。因此,也要對呼叫標籤出現異常時進行處理。因此對上述兩種異常進行綜合處理:
try:
badContent = bsObj.nonExistingTag.anotherTag
except AttributeError as e:
print("Tag was not found")
else:
if badContent == None:
print ("Tag was not found")
else:
print(badContent)
用異常處理方法對上個例子進行重寫:
from urllib.request import urlopen
from urllib.error import HTTPError
from bs4 import BeautifulSoup
def getTitle(url):
try:
html = urlopen(url)
except HTTPError as e:
return None
try:
bsObj = BeautifulSoup(html.read(),"html.parser")
title = bsObj.body.h1
except AttributeError as e:
return None
return title
title = getTitle("http://www.pythonscraping.com/pages/page1.html")
if title == None:
print("Title could not be found")
else:
print(title)
5. 通過css來抓取所需結果
抓取css中所有指定的標籤
from urllib.request import urlopen
from bs4 import BeautifulSoup
html = urlopen("http://www.pythonscraping.com/pages/warandpeace.html")
bsObj = BeautifulSoup(html)
nameList = bsObj.findAll("span", {"class":"green"})
for name in nameList:
print(name.get_text())
在這裡使用了.get_text()獲取標籤內的文字內容,那什麼時候用get_text()?什麼時候保留標籤呢?
.get_text() 會把你正在處理的 HTML 文件中所有的標籤都清除,然後返回一個只包含文字的字串。 假如你正在處理一個包含許多超連結、段落和標籤的大段原始碼, 那麼 .get_text() 會把這些超連結、段落和標籤都清除掉,只剩下一串不帶標籤的文字。
用 BeautifulSoup 物件查詢你想要的資訊,比直接在 HTML 文字里查詢資訊要簡單得多。 通常在你準備列印、儲存和運算元據時,應該最後才使用 .get_text()。
一般情況下,你應該儘可能地保留 HTML 文件的標籤結構。
6. BeautifulSoup的find()和findAll()
定義:
find(tag, attributes, recursive, text, keywords)
findAll(tag, attributes, recursive, text, limit, keywords)
引數的含義:
標籤引數 tag —可以傳一個標籤的名稱或多個標籤名稱組成的 Python列表做標籤引數。
.findAll({“h1”,”h2”,”h3”,”h4”,”h5”,”h6”})
屬性引數 attributes—用一個 Python 字典封裝一個標籤的若干屬性和對應的屬性值。
.findAll(“span”, {“class”:{“green”, “red”}})
遞迴引數 recursive 是一個布林變數 。
預設值是true,會去查詢標籤的子標籤,如果設為false,只會查一級標籤。
文字引數 text 有點不同,它是用標籤的文字內容去匹配,而不是用標籤的屬性。
nameList = bsObj.findAll(text="the prince")
print(len(nameList))
範圍限制引數 limit -只用於findAll方法。find其實就是findAll的limit等於1時的情形。
關鍵詞引數 keyword,可以讓你選擇那些具有指定屬性的標籤。
任何用關鍵詞引數能夠完成的任務,同樣可以用其他技術解決。
7. 處理層級標籤
給定一個指定的頁面結構如下所示:
html
— body
— div.wrapper
— h1
— div.content
— table#giftList
— tr
— th
— th
— th
— th
— tr.gift#gift1
— td
— td
— span.excitingNote
— td
— td
— img
— ……其他表格行省略了……
— div.footer
處理子標籤和其後代標籤
from urllib.request import urlopen
from urllib.error import HTTPError
from bs4 import BeautifulSoup
#子標籤處理
def getChild(url):
try:
html = urlopen(url)
except HTTPError as e:
return None
try:
bsobj = BeautifulSoup(html,"html.parser")
except AttributeError as e:
return None
return bsobj
bs_obj = getChild("http://www.pythonscraping.com/pages/page3.html")
for child in bs_obj.find("table",{"id":"giftList"}).children:
print(child)
處理兄弟標籤:
def getSibling(url):
try:
html = urlopen(url)
except HTTPError as e:
print(e)
return None
try:
bsObj = BeautifulSoup(html,"html.parser")
except AttributeError as e:
print(e)
return None
return bsObj
bs_obj = getSibling("http://www.pythonscraping.com/pages/page3.html")
for sibling in bs_obj.find("table",{"id":"giftList"}).tr.next_siblings:
print(sibling)
如果我們選擇 bsObj.table.tr 或直接就用 bsObj.tr 來獲取表格中的第一行,上面的程式碼也可以獲得正確的結果。 但是,我們還是採用更長的形式寫了一行程式碼,這可以避免各種意外:bsObj.find(“table”,{“id”:”giftList”}).tr
即使頁面上只有一個表格(或其他目標標籤),只用標籤也很容易丟失細節。另外,頁面佈局總是不斷變化的。一個標籤這次是在表格中第一行的位置,沒準兒哪天就在第二行或第三行了。 如果想讓你的爬蟲更穩定,最好還是讓標籤的選擇更加具體。如果有屬性,就利用標籤的屬性。
處理父標籤:
在爬蟲抓取網頁時,查詢父標籤的次數很少,但是還需要了解一下。
def getParent(url):
try:
html = urlopen(url)
except HTTPError as e:
print(e)
return None
try:
bs_obj = BeautifulSoup(html,"html.parser")
except AttributeError as e:
print(e)
return None
return bs_obj
bsObj = getParent("http://www.pythonscraping.com/pages/page3.html")
print(bsObj.find("img",{"src":"../img/gifts/img1.jpg"}).parent.previous_sibling.get_text())
8.正規表示式和BeautifulSoup
注意觀察網頁上有幾個商品圖片——它們的原始碼形式如下:
img src=”../img/gifts/img3.jpg”
用正規表示式對其進行擷取查詢
from urllib.request import urlopen
from urllib.error import HTTPError
from bs4 import BeautifulSoup
import re
def getImage(url):
try:
html = urlopen(url)
except HTTPError as e:
print(e)
return None
try:
bs_obj = BeautifulSoup(html,"html.parser")
except AttributeError as e:
print(e)
return None
return bs_obj
bsObj = getImage("http://www.pythonscraping.com/pages/page3.html")
patten = re.compile(r'\.\./img/gifts/img.*\.jpg')
images = bsObj.findAll("img",{"src":re.compile(patten)})
for image in images:
print(image["src"])
9. 獲取屬性
myTag.attrs
要注意這行程式碼返回的是一個 Python 字典物件,可以獲取和操作這些屬性。比如要獲取圖片的資源位置 src,可以用下面這行程式碼:
myImgTag.attrs[“src”]
10. Lambda表示式
Lambda 表示式本質上就是一個函式, 可以作為其他函式的變數使用;也就是說,一個函
數不是定義成 f(x, y),而是定義成 f(g(x), y),或 f(g(x), h(x)) 的形式。
#下面的程式碼就是獲取有兩個屬性的標籤:
soup.findAll(lambda tag: len(tag.attrs) == 2)
#這行程式碼會找出下面的標籤:
<div class="body" id="content"></div>
<span style="color:red" class="title"></span>
11.其他庫
lxml
這個庫可以用來解析 HTML 和 XML 文件,以非常底層的實現而聞名於世,大部分原始碼是用 C 語言寫的,在處理絕大多數 HTML 文件時速度都非常快。
相關文章
- java 爬蟲大型教程(一)Java爬蟲
- 《Python3網路爬蟲開發實戰》教程||爬蟲教程Python爬蟲
- python網路爬蟲_Python爬蟲:30個小時搞定Python網路爬蟲視訊教程Python爬蟲
- 網路爬蟲爬蟲
- Python3 大型網路爬蟲實戰 — 給 scrapy 爬蟲專案設定為防反爬Python爬蟲
- 網路爬蟲——爬蟲實戰(一)爬蟲
- Python大型網路爬蟲專案開發實戰(全套)Python爬蟲
- 網路爬蟲精要爬蟲
- 網路爬蟲示例爬蟲
- 大型商城網站爬蟲專案實戰網站爬蟲
- 網路爬蟲的原理爬蟲
- 網路爬蟲專案爬蟲
- 傻傻的網路爬蟲爬蟲
- [Python] 網路爬蟲與資訊提取(1) 網路爬蟲之規則Python爬蟲
- 《用Python寫網路爬蟲》--編寫第一個網路爬蟲Python爬蟲
- pyspider 爬蟲教程(二):AJAX 和 HTTPIDE爬蟲HTTP
- Python3 大型網路爬蟲實戰 003 — scrapy 大型靜態圖片網站爬蟲專案實戰 — 實戰:爬取 169美女圖片網 高清圖片Python爬蟲網站
- python網路爬蟲應用_python網路爬蟲應用實戰Python爬蟲
- 什麼是Python網路爬蟲?常見的網路爬蟲有哪些?Python爬蟲
- python網路爬蟲(14)使用Scrapy搭建爬蟲框架Python爬蟲框架
- 爬蟲學習之基於Scrapy的網路爬蟲爬蟲
- python DHT網路爬蟲Python爬蟲
- 網路爬蟲的反扒策略爬蟲
- 什麼是網路爬蟲爬蟲
- 什麼是網路爬蟲?爬蟲
- 網路爬蟲是什麼?爬蟲
- 網路爬蟲如何運作?爬蟲
- 網路爬蟲流程總結爬蟲
- 網路爬蟲專案蒐集爬蟲
- 網路爬蟲三大特性爬蟲
- 網路爬蟲(六):實戰爬蟲
- Python爬蟲初學二(網路資料採集)Python爬蟲
- 網路爬蟲——爬百度貼吧爬蟲
- Python3 大型網路爬蟲實戰 004 — scrapy 大型靜態商城網站爬蟲專案編寫及資料寫入資料庫實戰 — 實戰:爬取淘寶Python爬蟲網站資料庫
- python網路爬蟲(9)構建基礎爬蟲思路Python爬蟲
- 精通Scrapy網路爬蟲【一】第一個爬蟲專案爬蟲
- 爬蟲(9) - Scrapy框架(1) | Scrapy 非同步網路爬蟲框架爬蟲框架非同步
- 爬蟲學習之一個簡單的網路爬蟲爬蟲