Python學習六:web數據抓取與分析

《毫無障礙學Python》鄧文淵著 學習筆記

web數據抓取與分析

1.網址解析

.
  通過Python的 urlparse組件中的 urlparse函數,可對網址進行解析,其返回值爲元組類型的ResultParse對象,通過其對象的屬性可得到網地址中的個項數據

ResultParse函數屬性

索引值 返回值 不存在的返回值
scheme 0 返回scheme通訊協議 空字符串
netloc 1 返回網站名稱 空字符串
path 2 返回path路徑 空字符串
params 3 返回url查詢參數((params)字符串 空字符串
query 4 返回query字符串,即GET參數; 空字符串
fragment 5 返回框架名稱 空字符串
port 6 返回通信端口 None

解析中國天氣網南昌天氣的網址:http://www.weather.com.cn/weather1d/101240101.shtml#input

from urllib.parse import urlparse
url = 'http://www.weather.com.cn/weather1d/101240101.shtml#input'
o = urlparse(url)
print(o)

print("scheme={}".format(o.scheme))     # http
print("netloc={}".format(o.netloc))     # www.weather.com.cn
print("port={}".format(o.port))         # None
print("path={}".format(o.path))         # /weather1d/101240101.shtml
print("query={}".format(o.query))       # 空

運行結果
在這裏插入圖片描述

2.網頁數據抓取

.
   requests用於抓取網頁源代碼由於他比內置urllib模塊好用,因此逐漸取代了urllib,抓取源碼後可用in或正則表達式搜索獲取所需數據
   導入requests,可用requests.get()函數模擬HTTP GET方法發出一個請求(Request)到遠程服務器(Server),當服務器接收請求後會響應(Response)並返回網頁內容(源代碼),設置正確的編碼格式,既可通過text屬性取得網址中源代碼。

(1) 獲取網頁源碼

import requests
url = 'http://music.taihe.com/'	#以千千音樂網站爲例
html = requests.get(url)    #print(type(html))爲<class 'requests.models.Response'>
#html.encoding='utf-8'  #以utf-8編碼抓取
print(html.text)    # html.text獲取網頁源碼

#取得網頁源碼後,即可對源碼加以處理,例:把每一行分割成列表並移除換行符
htmllist = html.text.splitlines()     #每一行分割成列表並移除換行符
for row in htmllist:
     print(row)
print(len(htmllist))

(2)搜索指定字符串

用text屬性取得的源碼爲一大串字符串 若想搜索其中指定 字符或字符串 可用in來完成

import requests
url = 'http://www.9ku.com/qingyinyue/'  #以九酷音樂網爲例
html = requests.get(url)
html.encoding = 'utf-8'
if "流水" in html.text:
    print("找到!")
            ##也可一行行搜索 ,並統計該字符串出現的次數
htmllist = html.text.splitlines()
n = 0
for row in htmllist:
    if "流水" in row:n+=1
print('找到{}次'.format(n))

運行結果:
在這裏插入圖片描述

用正則表達式(regular expression簡稱regex)(對字符串操作的一種邏輯公式)抓取網站內容複雜內容:超鏈接、電話號碼…

常見正則表達式
. 表示一個除換行符(\n)外的所有字符
^ 表示輸入行的開始
$ 表示輸入行的結束
* 表示前一個項目可以出現0次或無數次
+ 表示前一個項目可以出現1次或無數次
表示前一個項目可以出現0次或1次
[abc] 表示一個符號a或b或c的任何字符
[a-z] 表示一個符號a~z的任何字符
\ 表示後面的字符以常規字符處理
{m} 表示前面的項目必須正好出現m次
{m,} 表示前面的項目至少出現m次,最多可出現無數次
{m,n} 表示前面的項目至少出現m次,最多可出現n次
\d 表示一個數字,相當於[0123456789]或[0-9]
^ 求反運算,例[^a-d]表示除a,b,c,d外的所有字符
\D 一個非數字字符,即[^0-9]
\n 換行字
\r 換行符
\t tab製表符
\s 空格符,即[\r\t\n\f]
\S 非空格符,即[^\r\t\n\f]
\w 一個數字、字母或下劃線字符,相當於[0-9a-zA-Z_]
\W 一個非數字、字母或下劃線字符,即[\w]即[0-9a-zA-Z]

常見的正則表達式實例

正則表達式 實例
整數 [0-9]+ 12356
帶小數點的實數 [0-9]+.[0-9]+ 45.26
英文字符串 [A-Za-z]+ Python
變量名稱 [A-Za-z_][A-Za-z0-9_] _point
Emial [a-zA-Z0-9]+@[a-zA-Z0-9._]+ [email protected]
URL http://[a-zA-Z0-9./_]+ http://e-happy.com.tw/

.
   創建正則表達式對象:要使用正則表達式首先需導入re包,再用re包提供的compile方法創建一個正則表達式對象
      語法:import re
          pat = re.compile(’[a-z]+’)

   正則表達式對象包含的方法:
   match(string)  在string中查找符合正則表達式的規則的字符串,遇到第一個不符合的字符時結束,結果會存入match對象(object)中;若未找到符合的字符,返回None
   match對象包含的方法:

  1. group()   返回符合正則表達式的字符串,遇到第一個不符合的字符時結束,結果存入match對象(object)中;未找到符合字符返回None
  2. end()  返回match的結束爲置
  3. span()  返回(開始位置,結束位置)的元組對象
import re
pat = re.compile('[a-z]+')
m = pat.match('tem12po')    #簡單起見,將match對象的值賦值給m
print(m)
print(m.group())
print(m.start())
print(m.end())
print(m.span())

在這裏插入圖片描述


## re.match()方法:(可省略re.match()方法創建正則表達式的步驟)
import re
m = re.match(r'[a-z]+','tem12po')   #兩個參數,第一個習慣在參數前加‘r'告訴編譯器這個是正則表達式,第二個參數傳遞待搜索的字符串
print(m)

在這裏插入圖片描述


search(string) 在string中查找第一組符合正則表達式的字符串,找到後結束,結果存入match對象(object)中;若未找到符合的字符,返回None

## search(string)   在string中查找第一組符合正則表達式的字符串,找到後結束,結果存入match對象
#                   (object)中;若未找到符合的字符,返回None
import re
pat = re.compile('[a-z]+')
m = pat.search('3tem12po')
print(m)    #<_ser.SER_Match object;span=9(1,4),match='tem'>
if not m==None:
    print(m.group())    # tem
    print(m.start())    # 1
    print(m.end())      # 4
    print(m.span())     # (1,4)
 ## findall()        返回指定字符串中所有符合正則表達式的字串,並返回一個列表
import re
pat = re.compile('[a-z]+')
m = pat.findall('tem12po')
print(m)        # ['tem','po']

案例:抓取萬水書苑網站中所有E-mail賬號

import requests,re
regex = re.compile(r'[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+')   #建立正則表達式對象
url = 'http://www.wsbookshow.com/' 
html = requests.get(url)        #抓取http://wsbookshow.com/網站的源代碼
emails = regex.findall(html.text)   #在html.text中查詢所有Email賬號
for email in emails:
    print(email)

(3)網頁分析

網頁分析:HTML網頁結構:許多標籤組成<>

使用BeautifulSoup進行網頁抓取與解析
  導入BeautifulSoup後,先用requests包中的get方法取得網頁源碼,然後可用Python內建的html.parser解析器對源代碼進行解析,解析結果返回到BeautifulSoup對象sp中,語法:sp = BeautifulSoup(源代碼,‘html.parser’)

import requests,urllib3
from bs4 import BeautifulSoup

url = 'http://www.baidu.com'
html = requests.get(url)
html.encoding='utf-8'
sp = BeautifulSoup(html.text,'html.parser')

BeautifulSoup常用屬性和方法:(假設已創建BeautifulSoup類的對象sp)

屬性和方法
title 返回網頁標題
text 返回除去所有HTML標籤後的網頁內容
find 返回第一個符合條件的標籤,例:sp.find(“a”)
find_all() 返回所有符合條件的標籤,例:sp.find_all(“a”)
select() 返回指定CSS樣式(如id或class)的內容,返回值爲列表!,例:sp.select("#id")通過id抓取
data1 = sp.select('title')
print(data1)
data2 = sp.select('#head')#抓取id="head"的網頁源代碼內容  id注意加“#”
#print(data2)
data3 = sp.select(".head_wrapper")#可通過css類的類名head_wrapper進行搜索    class注意加“.”
#print(data3)
data4 = sp.find('a')#取得第一個標籤爲a的內容
#print(data4)
data5 = sp.find_all('a')#取得所有標籤爲a的內容
#print(data5)
    # find_all(屬性名稱:屬性內容)可抓取所有符合規定的tag(標籤)內容,第二個參數是字典數據類型,
data5 = sp.find_all("a",{"class":"mnav"})
#print(data5[0])
    #通過一個列表參數可以一次搜索多個標籤
data6 = sp.find_all(['a','title'])#用[]括起標籤名!
#print(data6)

抓取屬性內容:要抓取屬性內容必須使用get()方法
  語法:get(屬性名稱)

import requests
from bs4 import BeautifulSoup
url = 'http://www.baidu.com/'
html = requests.get(url)
html.encoding = 'gbk'
sp = BeautifulSoup(html.text,'html.parser')
links = sp.find_all(['a','img']) #同時抓取<a>和<img>
for link in links:
    href = link.get("href")#讀取href屬性值
    # 判斷是否爲非None,及是否以http://開頭
    if href != None and href.startswith("http://"):
        print(href)

運行結果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章