JB的Python之旅-爬蟲篇--urllib和Beautiful Soup

啃麪包是辛苦的,那就開始學習爬蟲吧,而學習爬蟲的初衷很簡單,爬圖爬圖,這就是學習的動力~html

1.爬蟲信息瞭解

1)爬蟲的定義:

先了解,什麼叫爬蟲,上度娘搜了一番,解釋以下:前端

網絡爬蟲(又被稱爲網頁蜘蛛,網絡機器人,在FOAF社區中間,更常常的稱爲網頁追逐者),是一種按照必定的規則,
自動地抓取萬維網信息的程序或者腳本。
複製代碼

而互聯網就猶如一張蜘蛛網,而爬蟲能夠模擬瀏覽器的行爲,作想作的事情,好比自動下載妹子圖、下載小說;

python

2)爲何選擇Python?

而實現爬蟲技術的語言有不少種,Java、 C++、Python均可以用來爬蟲,但爲何選擇Python,是由於Python有強大的第三方庫,能簡單快速的實現想要的功能,另外Python爬取內容後,也能用於數據挖掘跟分析,簡單是一條龍服務,git


3)爬蟲原理及過程

上面說起到,爬蟲是模擬瀏覽器的行爲,而瀏覽器獲取網頁信息的過程大體以下:web

發送請求->得到網頁->解析網頁->抽取並存儲內容
複製代碼

簡單的說,想服務器發起請求後,會獲得返回的頁面結果,經過解析頁面以後,能夠抽取想要的那部分信息,而後就能夠存儲在指定文檔或者入庫;ajax

而整個過程須要簡單瞭解http協議及網頁基本知識,好比POST\GET、html、JS等;

正則表達式

4)本章內容

4.1)urllib介紹,得到網頁內容<br>
4.2)介紹Beautiful Soup<br>
4.3)實戰<br>
複製代碼

2.URL

在開始前,有必要介紹下URL,由於URL是一切開端;
簡單的來說,URL就是在瀏覽器端輸入的 http://www.baidu.com 這個字符串。json

通俗地說,URL是Internet上描述信息資源的字符串,主要用在各類WWW客戶程序和服務器程序上。瀏覽器

採用URL能夠用一種統一的格式來描述各類信息資源,包括文件、服務器的地址和目錄等。服務器

URL的通常格式爲(帶方括號[]的爲可選項):
protocol :// hostname[:port] / path / [;parameters][?query]#fragment

URL的格式由三部分組成:

①第一部分是協議(或稱爲服務方式)。

②第二部分是存有該資源的主機IP地址(有時也包括端口號)。

③第三部分是主機資源的具體地址,如目錄和文件名等。

第一部分和第二部分用「://」符號隔開,

第二部分和第三部分用「/」符號隔開。

第一部分和第二部分是不可缺乏的,第三部分有時能夠省略。

舉例: 例:http://www.rol.cn.net/talk/talk1.htm

其計算機域名爲www.rol.cn.net。

超級文本文件(文件類型爲.html)是在目錄/talk下的talk1.htm。

這是瑞得聊天室的地址,可由此進入瑞得聊天室的第1室。

例:file://ftp.yoyodyne.com/pub/files/foobar.txt

上面這個URL表明存放在主機ftp.yoyodyne.com上的pub/files/目錄下的一個文件,文件名是foobar.txt。

爬蟲最主要的處理對象就是URL,會根據URL地址取得所須要的文件內容,而後對它進行進一步處理。

3.urllib

Python裏有一個內置的urllib庫,是學習爬蟲的基礎核心,而這個庫的做用是向服務器發出請求並得到網頁內容,也就是學習爬蟲的第一步

因爲用的是Python3,在Python3中只有惟一的urllib庫,而在Python2是有區分urllib2和urllib

在使用以前,一塊兒看看urllib庫有什麼東東

import urllib
print(dir(urllib))

輸出的結果:
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'error', 'parse', 'request', 'response']
複製代碼

能夠看到urllib除了以雙下劃線開頭結尾的內置屬性外,還有4個重要的屬性,分別是error,parse,request,response。

這4個屬性中最重要的當屬request了,它完成了爬蟲大部分的功能,咱們先來看看request是怎麼用的。

request的使用: request請求最簡單的操做是用urlopen方法,代碼以下:

import urllib.request
response = urllib.request.urlopen('http://www.baidu.com/')
result = response.read()
print(result)
複製代碼

運行結果以下:

b'<!DOCTYPE html>\n<!--STATUS OK-->\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n...
複製代碼

看到後一臉懵逼,把所有內容copy出來看,也並不是亂碼,內容跟網頁的源碼是一致的,但爲了美觀點,在讀取的時候改一下編碼,就變成這樣了(若是有編碼問題,也是一樣的處理方案):

import urllib.request
response = urllib.request.urlopen('http://www.baidu.com/')
result = response.read().decode("uft-8")
print(result)
複製代碼

運行結果以下:

!DOCTYPE html>
<!--STATUS OK-->
<html>
<head>
    
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge">
	<meta content="always" name="referrer">
複製代碼

從輸出的結果來看,至少有點層次感了,而這個就是咱們想要的網頁內容啦,4行代碼就能把網頁內容輸出,簡單吧~

上面的幾句,就能獲取到網頁信息,但若是想爬取視頻/圖片呢,如何處理?或者須要網頁的一些信息,也怎麼處理?

import urllib.request
head = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.4843.400 QQBrowser/9.7.13021.400"
}

pic_url = "http://e.hiphotos.bdimg.com/album/h%3D370%3Bq%3D90/sign=c4164900fbf2b211fb2e8349fabb1405/d043ad4bd11373f0562c40eca40f4bfbfbed04b5.jpg"
request = urllib.request.Request(pic_url,headers=head)
response = urllib.request.urlopen(request)  
result = response.read()

with open("ganglian.jpg","wb") as f :
    f.write(result)


#可是官方推薦是使用下面這種方式
path = "jb.png"
urllib.request.urlretrieve(pic_url,path)
複製代碼

4.Request

對於通常的網站,上面幾句就能獲取網頁信息,但對於企業而已,網頁裏的信息也是很重要的,他們會作一些手段,防止爬取,而這種狀況,惟一的辦法就是讓本身裝的更像瀏覽器。

首先,用瀏覽器看一個簡單的請求,好比用的Chrome瀏覽器, 按F12->network,而後地址欄輸入一個url打開網頁,就能夠查看request的headers,能夠把這個瀏覽器的headers信息複製下來使用。 requests head信息,而head信息有哪些(圖二)?

一次訪問,是包含了不少信息,一般假裝的是User-Agent這塊,那怎麼作?

這時候就須要用到urllib.request下的Request方法了,這個方法經常使用的就是傳兩個參數,url跟header,而這個header就是咱們要假裝的信息了,從上看能夠到一些信息,那手法就是這樣的:

import urllib.request

head = {
    "Host":"www.baidu.com",
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.4843.400 QQBrowser/9.7.13021.400",
    "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
}
request = urllib.request.Request("http://www.baidu.com",headers=head)
response = urllib.request.urlopen(request)
result = respone.read
print(response.read().decode('utf-8'))

而輸出的結果跟上面的例子是同樣的,不一樣的是,這裏把header信息修改下,這樣作的就好像真的是瀏覽器發送的同樣;
複製代碼

cookie

什麼叫cookie?指某些網站爲了辨別用戶身份、進行 session 跟蹤而儲存在用戶本地終端上的數據,這也意味着,若是想登陸這些網站,那咱們先手動登陸一次,登陸成功後,服務端會分配cookie,那咱們把cookie也發送過去,就能夠模擬成真正的用戶了。 那,咱們要怎麼作才能把咱們的cookie發送過去呢?

import urllib.request
import http.cookiejar
cookie=http.cookiejar.CookieJar() #聲明一個CookieJar對象實例來保存cookie
handler=urllib.request.HTTPCookieProcessor(cookie)
# 利用urllib.request庫的HTTPCookieProcessor對象來建立cookie
opener=urllib.request.build_opener(handler)
# 經過handler來構建opener
response=opener.open("http://www.jianshu.com/")
# 此處的open方法同urllib.request的urlopen方法,也能夠傳入request
for item in cookie:
    print('name=',item.name)
    print('value=',item.value)
複製代碼

這裏遇到了個坑,pytohn3中是加載http.cookiejar,http.cookies模塊,不是python2中的import cookielib。 注意CookieJar()是屬於http.cookiejar模塊,而不是http.cookies模塊,不然會報錯: 'module' object has no attribute 'CookieJar'

beautifulSoup

經過上面的方式,基本上能獲取到大部分網站的html代碼信息,那網頁信息獲取已經完成了,接下來就是數據解析了,解析用的較多的是Beautiful Soup、正則、xpath,正則很實用,可是須要記住匹配模式,入手成本高,那一塊兒瞭解下bs是啥玩意把~

beautifulSoup 「美味的湯,綠色的濃湯」
一個靈活又方便的網頁解析庫,處理高效,支持多種解析器。
利用它就不用編寫正則表達式也能方便的實現網頁信息的抓取
複製代碼

因而可知,bs是一個從html文件中提取數據的Python庫,是爬蟲利器~

bs庫下載: PyCharm直接安裝: File -> Default Settings -> Project Interpreter 選擇Python 3的版本 -> 點+號 -> 搜索beautifulsoup4 安裝便可

其餘方式的安裝,自行查詢~

使用方式

from bs4 import BeautifulSoup  
import urllib.request
head = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.4843.400 QQBrowser/9.7.13021.400"
}
request = urllib.request.Request("http://www.baidu.com",headers=head)
response = urllib.request.urlopen(request)
result = response.read().decode("utf-8")

soup = BeautifulSoup(result)  #建立 beautifulsoup 對象
print(soup.title)   #輸出soup 對象的內容,格式化輸出

若是想打開本地的html文件來建立對象,則這樣處理:
soup = BeautifulSoup(open('jb.html'))

這裏有一點須要注意下,直接這樣print的話,雖然能執行,可是會看到一場錯誤,以下:
 UserWarning: No parser was explicitly specified, so I'm using the best available HTML parser for this system ("html.parser").
 
 解決方案下面也列出了:
BeautifulSoup(YOUR_MARKUP})

to this:

 BeautifulSoup(YOUR_MARKUP, "html.parser")
 
 意思很明顯,在建立對象時指定解析器,html.parser是內置的 html解析器,也能夠用lxml.parser
複製代碼

四大對象種類

Beautiful Soup 將複雜HTML文檔轉換成一個複雜的樹形結構,每一個節點都是 Python 對象,全部對象能夠概括爲4種:
Tag
NavigableString
BeautifulSoup
Comment
下面咱們進行一一介紹:
1)Tag(標籤)
Tag 是什麼?通俗點講就是 HTML 中的一個個標籤,須要注意,只會返回全部內容中第一個符合要求的標籤,例如:

<title>The Dormouse's story</title>
<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>  
上面的 title a 等等 HTML 標籤加上裏面包括的內容就是 Tag

    print(soup.title)
    
    print(soup.head)
    
    print(soup.a)
    
    print(soup.p)
複製代碼

對於tag來講,有兩個重要的屬性,是name和attrs

print soup.name
print soup.head.name
複製代碼

soup 對象自己比較特殊,它的 name 即爲 [document],對於其餘內部標籤,輸出的值便爲標籤自己的名稱。

attrs

print soup.p.attrs
\#{'class': ['title'], 'name': 'dromouse'}  
複製代碼

這裏把P標籤的全部屬性都打印出來,獲得的類型是一個字典,能夠經過鍵取值(print(soup.p['class'])),也可使用get方法經過傳入屬性的名稱(print(soup.p.get('class')) 也能夠對屬性和內容進行修改,如soup.p['class'] = "jbtest",print(soup.p)

NavigableString(標籤內部文字) soup.p.string

BeautifulSoup(文檔的所有內容) 跟Tag相像,能夠分別獲取它的類型、名稱、屬性

Comment(特殊類型的 NavigableString ) 輸出的內容不包括註釋符號,但在使用前,須要判斷下類型:

if type(soup.a.string)==bs4.element.Comment:
    print soup.a.string  
複製代碼

實戰說明:

想爬取網上內容,簡單瞭解下,大部分網頁都是下面狀況之一:
1)一個網頁包括全部信息,不須要點擊下一頁(若是須要點擊下一頁的,其實原理也同樣,只是在URL後面加個page便可)
2)沒有分頁功能,須要滑動到底部,纔會繼續加載

實戰1:下載小說

由於全職高手出了TV版,以爲還不錯,就沉迷小說了,前段時間據說有更新了,以前就是用瀏覽器打開網頁小說,而後在線一頁一頁翻,恰好如今學了爬蟲,試試看(壞笑)

網頁連接:http://www.biqukan.com/2_2675/

打開網頁看了下,下面紅框裏的內容就是須要的內容,點擊發現裏面仍是一個網頁,而後就是小說正文內容,那大體想了下,流程應該是這樣的:

1)獲取下圖須要的網頁信息,而且把每章小說的URL獲取出來
2)打開小說的URL,把正文獲取出來
3)獲取小說的標題,把回去的正文寫到本地
複製代碼

1)獲取下圖須要的網頁信息,而且把每章小說的URL獲取出來
打開網頁,按F12打開開發者工具,選擇Elements選項(默認就是這選項),而後點擊Elements選項左邊兩個的圖標按鈕(以下圖1),點擊後,圖標按鈕會變藍色,而後把鼠標移動到網頁上,而後在須要的地方進行點擊(如圖2),點擊後右邊的Elements就會自動定位到這裏區域上(如圖3)

而後在Elements往上翻,發現這些信息都是在一個class叫listman裏面,全局搜索了下,發現這個listman是惟一的,所以能夠直接使用find_all直接查找這個叫listman,而後拿到一個對象,裏面的內容就是listman下的

接下來是先把非a標籤無關的過濾點,過濾後是這樣的:

觀察這個結果,發現前12章不是我想要的,看了下網頁結構,前12章就是最新章節列表,但不是咱們須要的,因此也要過濾下前12章過濾章節

到這裏,每章的小說URL獲取出來的;

2)打開小說的URL,把正文獲取出來 小說URL:http://www.biqukan.com/2_2675/1008632.html,打開後繼續按照剛剛的套路,F12,點擊小說正文區域,獲得的信息就是這堆正文是在一個叫showtxt的class裏面且showtxt是全局惟一,也按照剛剛的套路獲取,裏面的東西就是咱們想要的正文啦~(開心臉)

小說連接、小說名稱、正文都有了,就能夠進行讀寫了,至此,小說就保存下來啦~

但由於樓主用的是win10的系統,在實際操做上,遇到一個Windows特有的問題--編碼問題,那就是在寫文件的時候,會報錯: UnicodeEncodeError: 'gbk' codec can't encode character '\xa0' in position 4033: illegal multibyte sequence

那解決方案就是在寫的時候指定編碼格式,好比encoding = 'utf-8'來解決問題

另外要注意,若是文件下載是指定目錄,建議判斷對應文件夾是否存在,不存在則先建立,不然也會報錯

腳本代碼以下:

# -*- coding: utf-8 -*-
import urllib.request
from bs4 import BeautifulSoup
from urllib import error
import os

novel_url = "http://www.biqukan.com/2_2675/"   #小說地址
novel_base_url = "http://www.biqukan.com/"     #小說首頁地址,拼接使用
save_dir = "Novel/"                            #下載小說的存放目錄

#獲取全部章節的url信息
def get_download_url():
    download_req = urllib.request.Request(novel_url)
    download_res = urllib.request.urlopen(download_req,timeout=20)
    download_content = download_res.read()
    download_soup = BeautifulSoup(download_content,"html.parser")

    listmain = download_soup.find_all(attrs={'class':'listmain'})
    a_list = []

    for i in listmain:
        if 'a' not in str(i):
            continue
        for d in i.findAll('a'):
            a_list.append(d)
    result_list = a_list[12:]
    return result_list

#獲取正文內容而且開始下載
def get_download_content(c):
    download_url = novel_base_url + c.attrs.get('href')
    download_name = c.string
    download_req = urllib.request.Request(download_url)
    download_response = urllib.request.urlopen(download_req,timeout=20)
    download_content = download_response.read()
    download_soup = BeautifulSoup(download_content,'html.parser')

    showtxt = download_soup.find_all(attrs={'class':'showtxt'})
    for txt in showtxt:
        save_novel(txt,save_dir+download_name+".txt")



#get_text()方法:用來獲取標籤裏面的文本內容,在括號裏面加"strip=True"能夠去除文本先後多餘的空格
#保存小說到本地
def save_novel(txt,path):
    try:
        if not os.path.exists(save_dir):
            os.makedirs(save_dir)
        with open(path,"w",encoding="utf-8") as f:
            f.write(txt.get_text(strip=True))
    except (error.HTTPError,OSError) as e:
        print(str(e))
    else:
        print('download success :'+path)


if __name__ == '__main__':
    novel_list = get_download_url()
    for content in novel_list:
        get_download_content(content)
複製代碼

實戰2

爬取百度圖片裏的圖片,網站特色:下滑會自動加載更多內容,沒有上下一頁的按鈕

工做上常常須要用到圖片,而後每次都要網上搜,並且還要去各類網站,比較麻煩,因此想着效果是:提供腳本輸入關鍵字,而後在百度圖片處進行相關下載到本地

思路就是:
1)用戶執行腳本後,手動輸入想輸入的內容
2)拼接URL,進行爬取
3)獲取HTML,拿到結果寫入數據

說幹就幹,先打開百度圖片首頁:http://image.baidu.com/

隨便搜索一個內容:鋼之鍊金術師
https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=index&fr=&hs=0&xthttps=111111&sf=1&fmq=&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=%E9%92%A2%E4%B9%8B%E7%82%BC%E9%87%91%E6%9C%AF%E5%B8%88&oq=%E9%92%A2%E4%B9%8B%E7%82%BC%E9%87%91%E6%9C%AF%E5%B8%88&rsp=-1

看了下連接,搜索的內容去哪裏了?一臉懵逼後嘗試查一下英文字符

在搜索個英文:test
https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=index&fr=&hs=0&xthttps=111111&sf=1&fmq=&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=test

此次能看出,word後面帶的就是輸入的內容了,所以想搜索什麼,就把word後面的value修改對應的詞就好啦~

可是,那上面的word 後面的這串是什麼鬼?「%E9%92%A2%E4%B9%8B%E7%82%BC%E9%87%91%E6%9C%AF%E5%B8%88」

作個實驗:

kw = urllib.request.quote("鋼之鍊金術師")
print(kw)

輸出的結果:
%E9%92%A2%E4%B9%8B%E7%82%BC%E9%87%91%E6%9C%AF%E5%B8%88
複製代碼

嗯,發現這個結果跟上面的是如出一轍的,而這個quote函數就是用於屏蔽特殊字符的,好比空格、中文等,由於URL只容許部分ASCLL(數字字母和部分符號),其餘的字符(包括漢字)是不符合URL的標準,因此URL須要對這些字符進行URL編碼,URL編碼的方式是把須要編碼的字符轉化爲 %xx 的形式。一般 URL 編碼是基於 UTF-8 的,函數說明也說起到給予UTF-8進行encode~

回到重點,那拼接網頁就是:....(前面一大坨)+word="想搜索的內容"

http://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=%E9%92%A2%E7%82%BC%E5%A3%81%E7%BA%B8&pn=0&gsm=64&ct=&ic=0&lm=-1&width=0&height=0

看了下網頁的結構,信息都在一個叫imgpage的class裏面,而它的children裏面,class是imgitem就是咱們所須要的~ 看了下,imgpage並非惟一,但裏面的內容都是咱們須要的,所以咱們須要提取全部class叫imgpage的內容

因而就寫下了imgpage_list = get_url_soup.findAll(attrs={"class":"imgpage"}),結果執行後發現,尼瑪,空的???

空就表明沒有這個class,就想着把這個soup打印出來看,結果,驚呆了~

這尼瑪,爲何打出來的是JS???例子1直接打印suop但是html的內容:

覺得是代碼哪裏錯了,反覆檢查,貌似都沒問題啊,無助之下,只能求助,結果科普了下,例子1爬取的網站是靜態的,在頁面中右鍵查看源碼就能看到圖片中的位置,就能把頁面源碼保存後解析獲取內容

但百度圖片這個網站,選擇圖片是能顯示圖片的位置和樣式,可是右鍵查看源碼,發現都是JS,是沒有任何連接信息,緣由是由於,百度圖片的網頁是一個動態頁面,它的網頁原始數據實際上是沒有這個個圖片,是經過運行JS,把這個圖片的數據插入到網頁的html標籤裏面,這樣形成的結果是,按F12雖然能看到這個標籤,但實際去獲取的時候,是沒有這個標籤的,它只在運行時加載和渲染,那這種狀況怎樣才能把圖片下載下來?答案是抓包

首先說明下,經過JS去作,好處時能夠異步去加載或者處理,而百度圖片就是一個例子,所以要看的是異步的數據,仍是原來的網頁,F12,選擇network,選擇XRH~

XRH是什麼?XHR 全稱:XMLHttpRequest,提供了對 HTTP 協議的徹底的訪問,而ajax經過原生的XMLHttpRequest對象發出HTTP請求,獲得服務器返回的數據後,再進行處理。

而ajax = Asynchronous JavaScript and XML(異步的 JavaScript 和 XML)

所以明白了,Chrome的XRH是用來記錄ajax的請求,而百度圖片用的就是ajax,所以就是這XRH看數據了~

回到上文,選擇XRH後,是沒有數據的,刷新下網頁,發現出現了一條請求,可是分析後發現沒有什麼做用,而後就模擬下用戶行爲,不停的下滑刷新圖片,結果就發現不一樣下滑的時候,會重複出現一條相似同樣的請求,點擊請求後再點擊Preview,看到是一個jsonshuj ,點開data,能看到這裏面有30條數據,隨意點擊一條展開後發現,須要的數據就在這裏面了,內容有多條url信息,手動打開後發現這幾個URL都是能夠下載所需的圖片~

整理下信息,回頭看,百度圖片一開始只加載30張圖片,當下滑時,頁面會動態加載一條json數據,每次json數據裏面包含30條信息,信息裏面包含圖片的URL,JS會把這些URL解析並顯示,從而達到每次滾動底部又多出30張圖片~

URL獲取了,那怎麼滑動操做呢?接下來就分析下,一直出現的json數據有沒有規律?

點擊Headers,對比請求信息,發現大多數字段都是保持不變,惟有pn字段是每次以30的步長遞增,這跟上面說的30張圖片不就對應的上嗎?(壞笑)

固然,還有queryWord跟word的值都是想要搜索的內容,所以把請求的URL copy出來,到瀏覽器上訪問:

在裏面直接搜索圖片的下載關鍵字,好比thumbURL,發如今能這個網頁上查詢到,而且圖片正常,記下來就是直接用文本提取就行了
https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=%E9%92%A2%E4%B9%8B%E7%82%BC%E9%87%91%E6%9C%AF%E5%B8%88&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&word=%E9%92%A2%E4%B9%8B%E7%82%BC%E9%87%91%E6%9C%AF%E5%B8%88&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&pn=60&rn=30&gsm=3c&1524867815458=

基本上,流程已經分析完了,貼上源碼

import urllib.request
from bs4 import BeautifulSoup
import urllib.parse
import re
import os
path = "pic/"
import json
# pn就是圖片量,20一頁,對應第一頁,40對應第二頁
pic_url = "https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=%E9%92%A2%E4%B9%8B%E7%82%BC%E9%87%91%E6%9C%AF%E5%B8%88" \
          "&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&word=%E9%92%A2%E4%B9%8B%E7%82%BC%E9%87%91%E6%9C%AF%E5%B8%88&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&pn=90&rn=60&gsm=3c&1524867815458="

heads= {
     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36',
     "referer":"https://image.baidu.com"
}

def get_download_url():
    get_url_request = urllib.request.Request(pic_url,headers=heads)
    get_url_response = urllib.request.urlopen(get_url_request,timeout=20)
    get_url_context = get_url_response.read().decode("utf-8")


    pic_url1 = re.findall("thumbURL:https", get_url_context, re.S)

    count = 0

    for i in range(len(pic_url)):
        begin = get_url_context.find("thumbURL",count)

        end = get_url_context.find("jpg",begin)

        download_url = get_url_context[begin+11:end+3]

        #字符串判空
        if download_url:
            if not os.path.exists(path):
                os.mkdir(path)
            urllib.request.urlretrieve(download_url,path+str(i+1)+".png")

        count = end


if __name__ == "__main__":
    get_download_url()
複製代碼

本章節就結束到這裏了~

小結:

本文主要介紹了Python自帶的urllib的用法,而且也介紹bs如何使用,結合兩個實戰案例,基本上對這塊的使用理解會更新~
下篇會介紹requests跟Scrapy,敬請期待~

最後再說點 原本以前規劃不少東西,可是由於最近比較忙,進度很是慢,並且有點事情耽擱,python這塊後面會隨緣更新,瞭解到什麼知識就寫什麼文章上去,主要涉及到測試、前端、python、git等等~

參考文獻:
https://blog.csdn.net/qq_32166627/article/details/60882964
https://blog.csdn.net/xiligey1/article/details/73321152

感謝支持~

相關文章
相關標籤/搜索