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

jb發表於2018-05-15

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

1.爬蟲資訊瞭解

1)爬蟲的定義:

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

網路爬蟲(又被稱為網頁蜘蛛,網路機器人,在FOAF社群中間,更經常的稱為網頁追逐者),是一種按照一定的規則,
自動地抓取全球資訊網資訊的程式或者指令碼。
複製程式碼

而網際網路就猶如一張蜘蛛網,而爬蟲可以模擬瀏覽器的行為,做想做的事情,比如自動下載妹子圖、下載小說;

2)為什麼選擇Python?

而實現爬蟲技術的語言有很多種,Java、 C++、Python都可以用來爬蟲,但為什麼選擇Python,是因為Python有強大的第三方庫,能簡單快速的實現想要的功能,另外Python爬取內容後,也能用於資料探勘跟分析,簡單是一條龍服務,


3)爬蟲原理及過程

上面提及到,爬蟲是模擬瀏覽器的行為,而瀏覽器獲取網頁資訊的過程大致如下:

傳送請求->獲得網頁->解析網頁->抽取並儲存內容
複製程式碼

簡單的說,想伺服器發起請求後,會得到返回的頁面結果,通過解析頁面之後,可以抽取想要的那部分資訊,然後就可以儲存在指定文件或者入庫;

而整個過程需要簡單瞭解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 這個字串。

通俗地說,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資訊有哪些(圖二)?

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

一次訪問,是包含了很多資訊,通常偽裝的是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)

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

然後在Elements往上翻,發現這些資訊都是在一個class叫listman裡面,全域性搜尋了下,發現這個listman是唯一的,因此可以直接使用find_all直接查詢這個叫listman,然後拿到一個物件,裡面的內容就是listman下的

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

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

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

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

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

2)開啟小說的URL,把正文獲取出來 小說URL:http://www.biqukan.com/2_2675/1008632.html,開啟後繼續按照剛剛的套路,F12,點選小說正文區域,得到的資訊就是這堆正文是在一個叫showtxt的class裡面且showtxt是全域性唯一,也按照剛剛的套路獲取,裡面的東西就是我們想要的正文啦~(開心臉)

JB的Python之旅-爬蟲篇--urllib和Beautiful Soup
小說連結、小說名稱、正文都有了,就可以進行讀寫了,至此,小說就儲存下來啦~

但因為樓主用的是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,拿到結果寫入資料

JB的Python之旅-爬蟲篇--urllib和Beautiful Soup
說幹就幹,先開啟百度圖片首頁: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”

JB的Python之旅-爬蟲篇--urllib和Beautiful Soup
做個實驗:

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的內容

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

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

空就代表沒有這個class,就想著把這個soup列印出來看,結果,驚呆了~

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

這尼瑪,為什麼打出來的是JS???例子1直接列印suop可是html的內容:

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

以為是程式碼哪裡錯了,反覆檢查,貌似都沒問題啊,無助之下,只能求助,結果科普了下,例子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都是可以下載所需的圖片~

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

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

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

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

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

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

當然,還有queryWord跟word的值都是想要搜尋的內容,因此把請求的URL copy出來,到瀏覽器上訪問:

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

在裡面直接搜尋圖片的下載關鍵字,比如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

感謝支援~

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

相關文章