程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python爬蟲之Urllib(內置庫)

編輯:Python

活動地址:CSDN21天學習挑戰賽

以下是關於Python~Urllib內置庫的使用
🥧快,跟我一起爬起來



Urllib庫(Python內置庫)

  • 爬蟲
    • 什麼是爬蟲
    • 爬蟲核心
    • 爬蟲的用途
    • 爬蟲分類
    • 反爬的幾種手段
  • 爬蟲之Urllib的使用
    • 使用Uellib爬取百度首頁源碼
    • Response響應(一個類型 六個方法)
    • 使用Urllib簡單爬取圖片、視頻和百度源碼 (保存到本地)
  • 爬蟲之Urllib~UA反爬(定制對象)
  • 爬蟲之Unicode編解碼
    • get請求方式*單個參數
    • get請求方式*多個參數
  • 爬蟲之爬取百度翻譯(post請求)
    • 百度翻譯之Errno解析
    • 爬蟲之post 對比於 get
    • 普通的爬
    • 詳細爬(Cookie反爬)
  • 總結

提示:以下是本篇文章正文內容

爬蟲

什麼是爬蟲

  1. 網絡爬蟲(又稱為網頁蜘蛛,網絡機器人,在FOAF社區中間,更經常的稱為網頁追逐者),是一種按照一定的規則,自動地抓取萬維網信息的程序或者腳本。 通俗來講,假如你需要互聯網上的信息,如商品價格,圖片視頻資源等,但你又不想或者不能自己一個一個自己去打開網頁收集,這時候你便寫了一個程序,讓程序按照你指定好的規則去互聯網上收集信息,這便是爬蟲,我們熟知的 百度,谷歌 等搜索引擎背後其實也是一個巨大的 爬蟲 。
  2. 如果我們把互聯網比作一張大的蜘蛛網,那一台計算機上的數據便是蜘蛛網上的一個獵物,而爬蟲程序就是一只小蜘蛛,沿著蜘蛛網抓取自己想要的數據

解釋1:通過一個程序,根據Url(https://www.baidu.com/)進行爬取網頁,獲取有用信息
解釋2:使用程序模擬浏覽器,去向服務器發送請求,獲取響應信息

爬蟲核心

  1. 爬取網頁:爬取整個網頁 包含了網頁中所有得內容
  2. 解析數據:將網頁中你得到的數據 進行解析
  3. 難點:爬蟲和反爬蟲之間的博弈
  4. 反爬策略:

1、以浏覽器的形式訪問

2、部署多個應用分別抓取,降低單節點頻繁訪問

……

爬蟲的用途

  1. 12306搶票,網絡投票等
  2. 通過爬蟲爬取數據
  3. 去免費的數據網站爬取數據
    ……

爬蟲分類

  1. 通用爬蟲:
  • 功能:

    訪問網頁抓取數據數據存儲數據處理獲取數據

  • 缺點

    1. 抓取的數據大多是無用的
    2. 不能根據用戶的需求來精准獲取數據
  1. 聚焦爬蟲:
  • 功能:

    根據需求實現爬蟲程序抓取需要的數據

  • 設計思路

    1. 確定要爬取的url
      如何獲取Url
    2. 模擬浏覽器通過http協議訪問url,獲取服務器返回的html代碼
      如何訪問
    3. 解析html字符串(根據一定規則提取需要的數據)
      如何解析
  1. 增量式爬蟲 (爬取更新的頁面,新的信息)
  2. 深層網絡爬蟲(簡而言之,提交表單的深層頁面 構成:url列表,LVS列表,爬行控制器等)也是一些綱領性的內容,一定要有個底。

反爬的幾種手段

  1. User‐Agent:

    User Agent中文名為用戶代理,簡稱 UA,它是一個特殊字符串頭,使得服務器能夠識別客戶使用的操作系統及版本、CPU 類型、浏覽器及版本、浏覽器渲染引擎、浏覽器語言、浏覽器插件等。

  2. 代理IP:

    • 簡單的說,通過購買或使用免費(一般失敗)ip代理,從不同的ip進行訪問,這樣就不會被封掉ip了。
    • 什麼是高匿名、匿名和透明代理?它們有什麼區別?
      1、使用透明代理,對方服務器可以知道你使用了代理,並且也知道你的真實IP。
      2、使用匿名代理,對方服務器可以知道你使用了代理,但不知道你的真實IP。
      3、使用高匿名代理,對方服務器不知道你使用了代理,更不知道你的真實IP。
  3. 驗證碼:

    1、打碼平台
    2、雲打碼平台

  4. JavaScript 參與運算,返回的是js數據 並不是網頁的真實數據

    1. 解決方法:使用PhantomJS
    2. PhantomJS是一個可編程的無頭浏覽器.
    3. PhantomJS是一個Python包,他可以在沒有圖形界面的情況下,完全模擬一個浏覽器,js腳本驗證什麼的再也不是問題了。
  5. 職業選手級別(代碼混淆、動態加密方案、假數據,混淆數據等方式)

    • 解決方法:持續對抗,直到對方放棄
  6. 趕緊爬起來

爬蟲之Urllib的使用

Python庫的使用方法

使用Uellib爬取百度首頁源碼

# 引入urllib
import urllib.request
# 定義url
url = 'http://www.baidu.com/'
# 模擬浏覽器向服務器發送請求
response = urllib.request.urlopen(url)
# 獲取相應中的頁面源碼 content 內容
# read方法 返回的是字節形式的二進制數
# 二進制轉換為字符串
# 二進制字符串 簡稱解碼 decode('編碼的格式') 格式查看方法右鍵查看源碼 content="text/html;charset=utf-8"(utf-8就是編碼格式)
content = response.read().decode('utf-8')
print(content)

如圖所示爬取成功

這時ctrl+a ctrl+c ctrl+v 如下所示


Response響應(一個類型 六個方法)

  1. Response相應(一個類型 六個方法)
  2. 類型:HTTPResponse
  3. 方法:read readline readlines getcode geturl getheaders

使用如下:

# 引入urllib(內置庫不需要下載直接引入使用)
import urllib.request
# 定義url(爬取百度首頁信息)
url = 'https://www.baidu.com/'
# 模擬浏覽器向服務器發送請求
response = urllib.request.urlopen(url)
# response是Httpresponse的類型
print(type(response))
# 按照一個一個字節去讀
content = response.read()
print(content)
# 返回五個字節
content = response.read(5)
print(content)
# 讀取一行
content1 = response.readline()
print(content1)
# 讀取是一個狀態信息
content2 = response.readlines()
print(content2)
# 返回狀態碼 如200就證明我們的邏輯沒有錯
content3 = response.getcode()
print(content3)
# 返回Url
content4 = response.geturl()
print(content4)
# 獲取狀態信息
content5 = response.getheaders()
print(content5)

使用Urllib簡單爬取圖片、視頻和百度源碼 (保存到本地)


import urllib.request
url = 'http://www.baidu.com/'
# 讀
# response = urllib.request.urlopen(url)
# content=response.read()
# print(content)
//urllib.request.urlretrieve(url,文件路徑 或 文件名);
# 下載網頁
urllib.request.urlretrieve(url, '2、python之urllib內置函數下載文件到本地/baidu.html')
# 下載圖片
imgUrl = 'https://img1.baidu.com/it/u=1814112640,3805155152&fm=253&fmt=auto&app=120&f=JPEG?w=889&h=500'
urllib.request.urlretrieve(imgUrl, '2、python之urllib內置函數下載文件到本地/img.png')
# 下載視頻
videoUrl = 'https://vd3.bdstatic.com/mda-jbrihvz6iqqgk67a/sc/mda-jbrihvz6iqqgk67a.mp4?v_from_s=hkapp-haokan-hnb&auth_key=1655298996-0-0-c4eb8c0b81c04fsrc='
urllib.request.urlretrieve(videoUrl, '2、python之urllib內置函數下載文件到本地/video.mp4')

如下圖(下載保存到本地):

爬蟲之Urllib~UA反爬(定制對象)

跳轉UA反爬說明

語法:request = urllib.request.Request()

演示:

import urllib.request
url = 'https://www.baidu.com/'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36'
}
response = urllib.request.urlopen(url)
content = response.read().decode('utf-8')
print(content)

如圖(遇到了UA反爬):


解決獲得UA:
方法一:百度跳轉
方法二:開發工具找如 圖

得UA 定制 再次爬取

演示:

import urllib.request
url = 'https://www.baidu.com/'
//UA寫成字典形式
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36'
}
#因為Urlopen 方法中不能儲存字典 所以headers不能傳進去
#請求對象的定制
因為順序問題 不能直接寫Url 和 headers 中間又data 所以我們需要關鍵字傳參
簡單理解:偽裝一下
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)

如下圖(爬取成功):


爬蟲之Unicode編解碼

get請求方式*單個參數

引入 import urllib.parse
語法::urllib.parse.quote()

爬取鏈接:https://cn.bing.com/search?q=%E5%A4%A7%E5%8F%B8%E9%A9%AC

演示:

import urllib.request
import urllib.parse
url = 'https://cn.bing.com/search?q=%E5%A4%A7%E5%8F%B8%E9%A9%AC'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 '
'Safari/537.36',
}
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)

如圖所示(我們已經爬取成功了):

url = ‘https://cn.bing.com/search?q=%E5%A4%A7%E5%8F%B8%E9%A9%AC’

但是url後面的%E5%91%A8%E6%9D%B0%E4%BC%A6(Unicode編碼)讓我們很難受(我們怎麼才能直接把url變成 url = 'https://cn.bing.com/search?q=大司馬’)

這時就要用到編解碼

編解碼演示:

import urllib.request
import urllib.parse
# url = 'https://cn.bing.com/search?q=%E5%A4%A7%E5%8F%B8%E9%A9%AC'
url = 'https://www.baidu.com/s?wd='
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 '
'Safari/537.36',
}
#編解碼
name = urllib.parse.quote('大司馬')
url = url + name
print(url)
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)

如下圖所示(也是爬取成功的):


get請求方式*多個參數

引入 import urllib.parse
語法:urllib.parse.urlencode(data)

演示:


import urllib.request
import urllib.parse
url = 'https://cn.bing.com/search?'
data = {
'q': '大司馬',
'sex': '男',
}
new_data = urllib.parse.urlencode(data)
print(new_data)
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 '
'Safari/537.36',
}
url = url + new_data
print(url)
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)

如下圖所示(爬取成功):


爬蟲之爬取百度翻譯(post請求)

百度翻譯之Errno解析

  1. rrno:997 cookie失效
  2. errno:998 sign參數錯誤
  3. errno:999 post未提交from,to參數
  4. error:1000 需要翻譯的字符串為空 # 記住,這個是error,也許是百度發現自己的errno拼錯了吧

爬蟲之post 對比於 get

post VS get

  1. post請求的參數 必須要進行編碼
  2. 編碼後 必須調用encode方法
  3. post請求的參數是放在請求對象定制的參數中

import json

  • Python json.loads()用法
  1. 參數:它接受一個字符串,字節或字節數組實例,該實例包含JSON文檔作為參數。
  2. 返回:它返回一個Python對象。

普通的爬

普通爬如:

  • 找規律
  1. 爬蟲起始難度就在於找規律
  2. 如百度翻譯,當你輸入每個字母時他都會發送一個參數到後台返回數據
  3. 這個參數就是kw,最終把kw當作參數就可以爬了( 其他類似)
  4. 接口URL如


演示:

import urllib.request
import urllib.parse
url = 'https://fanyi.baidu.com/sug'
data = {
'kw': 'response'
}
data = urllib.parse.urlencode(data).encode('utf-8')
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 '
'Safari/537.36 '
}
request = urllib.request.Request(url=url, data=data, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)
print(type(content)) //<class 'str'>
import json
obj = json.loads(content)
print(obj)
print(type(obj)) //<class 'dict'>

如下圖所示(爬取成功):


詳細爬(Cookie反爬)

詳細爬如:

  • 接口&&參數


  • 遇到Cookie反爬反扒(解決方法如):
  1. 手動處理
    在開發手動捕獲cookie,將其封裝在headers中
    應用場景:cookie沒有有效時長且不是動態變化

  2. 自動處理
    使用session機制
    使用場景:動態變化的cookie
    session對象:該對象和requests模塊用法幾乎一致.如果在請求的過程中產生了cookie,如果該請求使用session發起的,則cookie會被自動存儲到session中

演示:

import urllib.request
import urllib.parse
url = 'https://fanyi.baidu.com/v2transapi?from=en&to=zh'
headers = {
'Cookie': 'BAIDUID=6E16BFD21056E02BFCBB6C181371A7BA:FG=1; BIDUPSID=6E16BFD21056E02BFCBB6C181371A7BA; PSTM=1657274923; BDUSS=R2clJMdHNPaGJ3OTlnaElVTjlTemVwN0ZGSmRwWDgxY3loc1VMUW9WZll2dzVqRVFBQUFBJCQAAAAAAAAAAAEAAAAz-QpaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANgy52LYMudiRl; BDUSS_BFESS=R2clJMdHNPaGJ3OTlnaElVTjlTemVwN0ZGSmRwWDgxY3loc1VMUW9WZll2dzVqRVFBQUFBJCQAAAAAAAAAAAEAAAAz-QpaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANgy52LYMudiRl; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; delPer=0; PSINO=6; BA_HECTOR=8h2g2k210525a421a12hoig31hehg8516; ZFY=TDJyUX98cot3iwdffZouzP1sZtAh37z5PDsJ8FRDb8g:C; BDRCVFR[C0p6oIjvx-c]=I67x6TjHwwYf0; H_PS_PSSID=36548_36752_36726_36413_36955_36948_36167_36917_36919_36966_36746_36863; BAIDUID_BFESS=810EC53BCDE6455B978B319AFAB64094:FG=1; APPGUIDE_10_0_2=1; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1659423222; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; ab_sr=1.0.1_MzI4MzNlOGUxOTA1NTRiZjE2NjM2ZjEzZDE3NTg3MTExMWVmYWNlNzhkYTM0NDczOGJmNTc4NjYwYzkwYjY5MmU2NWNmNmMxOTMxZDc1YmRlOTVkNjlhOTZjNDliNGM4ZWVkNWYxOWZlNGJlZjNiYWEwOGU0NWMzMjdlNWNhN2ExMTI0OTE2ZTI3OTcxNjYyNTgxMzA4MzQ1ZTc5NTdkOA==; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1659425248',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 '
'Safari/537.36',
}
data = {
'from': 'en',
'to': 'zh',
'query': 'response',
'simple_means_flag': '3',
'sign': '822261.551108',
'(這裡被監測出來了)': 'fee23791753041e39c8086e4ff32e770',
'domain': 'common'
}
data = urllib.parse.urlencode(data).encode('utf-8')
request = urllib.request.Request(url=url, data=data, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)
print(type(content))
import json
obj = json.loads(content) //<class 'str'>
print(obj)
print(type(obj)) //<class 'dict'>

如下圖所示(爬取成功):

總結

本文章到這裡就結束了,感謝大家的支持,希望這篇文章能幫到大家

下篇文章再見ヾ( ̄▽ ̄)ByeBye


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved