本博客內容來自韋瑋老師網絡爬蟲課堂筆記,僅用於個人學習和複習,請勿轉載用於其他商業用途。
1、爬蟲防屏蔽手段之代理服務器
使用代理服務器進行信息爬取,可以很好的解決IP限制的問題。
import urllib.request
def use_proxy(url, proxy_addr):
# 設置代理服務器:49.71.133.38爲代理服務器地址,9999爲代理服務器端口,中間使用冒號分隔
proxy = urllib.request.ProxyHandler({"http": proxy_addr})
# 由於urllib.request.urlopen不支持很多高級網頁,因此使用build_opener方法生成對象
opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler)# 第二個參數是固定的
# 將opener安裝爲全局變量
urllib.request.install_opener(opener)
data = urllib.request.urlopen(url).read().decode("utf-8", "ignore")
return data
proxy_addr ='183.154.51.142:9999'
url = "http://www.baidu.com"
data = use_proxy(url, proxy_addr)
print(len(data))
#
39691
我們在運行過程中使用的是西刺的免費代理服務器。其實在操作過程中,基本沒有代理服務器可以成功,看來如果想成功的話還是得花錢買專業版的……大部分出錯顯示如下:
urllib.error.URLError: <urlopen error [WinError 10060] 由於連接方在一段時間後沒有正確答覆或連接的主機沒有反應,連接嘗試失敗。>
或者
ConnectionResetError: [WinError 10054] 遠程主機強迫關閉了一個現有的連接。
或者
urllib.error.URLError: <urlopen error [WinError 10061] 由於目標計算機積極拒絕,無法連接。>
2、圖片爬蟲實戰
圖片爬蟲,是從互聯網中自動把對方服務器上的圖片爬下來的爬蟲程序。
首先我們登陸淘寶,選擇好固定的商品名稱,然後將網址複製下來:
https://s.taobao.com/list?spm=a21bo.2017.201867-links-0.23.5af911d9ptYTpF&q=%E8%83%8C%E5%BF%83%E5%90%8A%E5%B8%A6&cat=16&style=grid&seller_type=taobao
https://s.taobao.com/list?spm=a21bo.2017.201867-links-0.23.5af911d9ptYTpF&q=%E8%83%8C%E5%BF%83%E5%90%8A%E5%B8%A6&cat=16&style=grid&seller_type=taobao&bcoffset=0&s=60
https://s.taobao.com/list?spm=a21bo.2017.201867-links-0.23.5af911d9ptYTpF&q=%E8%83%8C%E5%BF%83%E5%90%8A%E5%B8%A6&cat=16&style=grid&seller_type=taobao&bcoffset=0&s=120
https://s.taobao.com/list?spm=a21bo.2017.201867-links-0.23.5af911d9ptYTpF&q=%E8%83%8C%E5%BF%83%E5%90%8A%E5%B8%A6&cat=16&style=grid&seller_type=taobao&bcoffset=0&s=180
通過觀察我們可以發現,在q=至&cat之間就是我們要搜索的商品的名字,而最後的s=60則代表頁碼,第一頁爲0,第二頁爲60,第三頁爲120,以此類推。因此,我們的網址可以簡化爲:
https://s.taobao.com/list?spm=a21bo.2017.201867-links-0.23.5af911d9ptYTpF&q=“商品名稱”&cat=16&style=grid&seller_type=taobao&bcoffset=0&s=“頁碼數”
至此,我們就分析出了網址的構造。然後我們對網址的圖片進行分析。
我們選中一張圖片右鍵複製圖片網址,並在新的瀏覽頁面中打開,得到了一張小圖片,這貌似不是我們想要的:
然後我們打開頁面源代碼,在其中搜索圖片的網址,並不能搜索到任何東西:
但是這不意味着,圖片信息一定隱藏在JS中了。
我麼再觀察一下圖片的網址:
我們把無關緊要的部分去掉,逐步留下核心的部分:
然後我們複製這個部分,再回到源碼頁面去找,果然找到了:
圖片顯示的格式如下:
g-search3.alicdn.com/img/bao/uploaded/i4/i1/51486753/O1CN01ZzJl9p1zkvCCizIQK_!!51486753.jpg
現在我們知道,這個就是圖片存放在服務器上的地址。雖然沒有http協議,但是我們在構造網址的時候可以將它構造出來。我們在瀏覽器中輸入地址,可以發現這張圖片是高清版原圖而非縮略圖:
這樣,我們就可以用正則表達式來提取圖片地址了。代碼如下:
import urllib.request
import re
keyname = "背心吊帶" # 如果希望搜索多次詞,可以建一個列表,通過for循環執行
# 由於不識別中文,我們需要將中文進行編碼
key = urllib.request.quote(keyname)
headers = ("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 SE 2.X MetaSr 1.0")
opener = urllib.request.build_opener()
opener.addheaders = [headers]
urllib.request.install_opener(opener)
for i in range(0, 3):
url = "http://s.taobao.com/list?spm=a21bo.2017.201867-links-0.23.5af911d9ptYTpF&q=" + key + "&cat=16&style=grid&seller_type=taobao&bcoffset=0&s=" + str(i*60)
data = urllib.request.urlopen(url).read().decode("utf-8", "ignore")
pat = 'pic_url":"//(.*?)"'
image_list = re.compile(pat).findall(data) # 所有圖片的網址
for j in range(0, len(image_list)):
this_image = image_list[j]
this_image_url = "http://" + this_image
file = "D:/PROGRAMMING/數據分析/Python數據分析與挖掘實戰視頻教程/實驗/img/" + str(i) + str(j) + ".jpg"
urllib.request.urlretrieve(this_image_url, filename=file)
看老師的視頻,確實是成功了,我自己這個代碼,毛都沒爬下來……然後我換了個火狐瀏覽器,還是毛都沒爬下來……
這就是傳說中的臉黑吧……
然後我把老師的源碼複製過來,改動了文件存儲地址,報頭那塊也做了適當調整,發現還是啥也沒有,說明這套技術已經不能在淘寶上面爬圖了嗎?我也搞不清……
3、實戰:爬取千圖網高清圖片
import urllib.request
import re
import urllib.error
for i in range(1, 10):
url = "https://www.58pic.com/piccate/10-0-0-p0" + str(i) + ".html"
data = urllib.request.urlopen(url).read().decode("utf-8", "ignore")
pat = '<img class="lazy" data-original="//(.*?).jpg!'
image_list = re.compile(pat).findall(data)
for j in range(0, len(image_list)):
try:
this_image = image_list[j]
this_image_url = "http://" + this_image + ".jpg!w1024_new_0"
file = "D:/PROGRAMMING/數據分析/Python數據分析與挖掘實戰視頻教程/實驗/img/" + str(i) + str(j) + ".jpg"
urllib.request.urlretrieve(this_image_url, filename=file)
print("第" + str(i) + "頁第" + str(j) + "個圖片爬取成功...")
except urllib.error.URLError as e:
if hasattr(e, "code"):
print(e.code)
if hasattr(e, 'reason'):
print(e.reason)
except Exception as e:
print(e)
#
第1頁第0個圖片爬取成功...
第1頁第1個圖片爬取成功...
第1頁第2個圖片爬取成功...
第1頁第3個圖片爬取成功...
第1頁第4個圖片爬取成功...
第1頁第5個圖片爬取成功...