爬虫 404 try_无所不能的Python之爬虫那点事儿
今天給大家介紹一個(gè)有趣的新技術(shù)——爬蟲。首先來講一下啥是爬蟲。
爬蟲也叫網(wǎng)絡(luò)爬蟲,是一種按照一定的規(guī)則,自動地抓取萬維網(wǎng)信息的程序或者腳本。通俗的來講,爬蟲就是一段程序,它來根據(jù)你的設(shè)定自己去互聯(lián)網(wǎng)上瀏覽網(wǎng)頁并把這些信息下載下來,然后在從中提取出有用的信息。這些信息可以用在做數(shù)據(jù)分析、數(shù)據(jù)統(tǒng)計(jì)等等。
接下來我會用通俗的語言來講解爬蟲技術(shù),這些都是基于我個(gè)人的理解所寫的,水平有限,若有不對的地方請指正。
我們平常瀏覽的眾多網(wǎng)站都是有對應(yīng)的源代碼的。如果你有興趣,可以用你電腦的任意瀏覽器打開一個(gè)網(wǎng)站,然后按一下F12試試。此時(shí)你會看到:網(wǎng)頁里所有的文字、圖像、聲音等等一切元素,都是由HTML源碼編排而成。你打開的這個(gè)窗口其實(shí)就是網(wǎng)頁源碼的調(diào)試窗口,當(dāng)你試著用鼠標(biāo)在那些源碼上移動時(shí),你會發(fā)現(xiàn)每移動到一個(gè)地方,網(wǎng)頁便會有對應(yīng)的地方高亮起來。也就是說,當(dāng)我們把這些被高亮的元素的源碼下載下來并解析出來,我們便獲取了這些元素。這便是爬蟲程序要干的事兒。
既然我們需要下載源碼,那我們首要的便是訪問這個(gè)網(wǎng)站。這里會出現(xiàn)一些問題:因?yàn)橛行┚W(wǎng)站有反爬蟲技術(shù),它會識別出你是爬蟲程序,并中斷你的訪問甚至是封鎖你的IP地址。這其中一個(gè)應(yīng)對方法就是我們的爬蟲程序里一定要寫好HTTP請求頭。HTTP請求頭是當(dāng)你正常用瀏覽器打開網(wǎng)頁時(shí),瀏覽器向網(wǎng)絡(luò)服務(wù)器發(fā)送的一些配置信息和屬性。我們就是用這個(gè)HTTP請求頭來偽裝成人類訪問用戶,以防止被服務(wù)器屏蔽。
如何構(gòu)造合理的 HTTP請求頭?
請求頭可以通過“requests”模塊自定義,例如
headers = {'User-Agent' : 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 4 Build/JOP40D)'' AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19'}headers = {'User-Agent': 'Chrome/68.0.3440.106', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '18', 'Content-Type': 'application/x-www-form-urlencoded'}經(jīng)我親身測試發(fā)現(xiàn),HTTP請求頭包含的這些內(nèi)容里最為重要的是“User-Agent“這個(gè)參數(shù)。我們在設(shè)置請求頭時(shí),其實(shí)只需要設(shè)置好它就足夠了。除了以上這個(gè)設(shè)置方法,還有一個(gè)較為簡單的辦法,那就是用python的fake_useragent模塊來設(shè)置,示例代碼如下:
#調(diào)用模塊的UserAgent類方法 from fake_useragent import UserAgent#實(shí)例化類方法 user_agent = UserAgent()#選擇chrome瀏覽器為User-Agent的值 headers = {'User-Agent':user_agent.chrome}#選擇ie瀏覽器為User-Agent的值 headers = {'User-Agent':user_agent.ie}#選擇firefox瀏覽器為User-Agent的值 headers = {'User-Agent':user_agent.firefox}#隨機(jī)選擇一款瀏覽器為User-Agent的值 headers = {'User-Agent':user_agent.random}請求頭設(shè)置完之后,我們便可以進(jìn)行下一步關(guān)鍵性的操作——爬取指定網(wǎng)頁信息。
如何爬取指定網(wǎng)頁的信息?
這次我們用到了requests模塊中的get方法,requests.get(url , headers)。通過給get方法傳遞網(wǎng)址參數(shù)url和Http頭信息headers便可以接收到網(wǎng)站的響應(yīng)response,這個(gè)response里包含著整個(gè)網(wǎng)頁的全部源代碼。這里我們應(yīng)該在代碼中寫好各種可能發(fā)生的情況,以此來提高代碼運(yùn)行時(shí)的穩(wěn)定性,防止崩潰。示例代碼如下:
from requests.exceptions import ReadTimeouttry:response = requests.get(url, headers=headers, timeout=0.5)if response.status_code == 200:return response.textreturn 404 except ReadTimeout:print('timeout') except Exception as e:print(e)示例中用的是python的異常處理標(biāo)識符——try、except。首先導(dǎo)入了requests模塊中的異常處理類型ReadTimeout,用來處理網(wǎng)站訪問超時(shí)響應(yīng)問題。其次Exception用來處理其他常規(guī)的問題。然后在判斷response參數(shù)的status_code的值是否是200,這個(gè)值是200說明服務(wù)器響應(yīng)成功了,如果不是,則返回404代碼。表示404 NotFound服務(wù)器響應(yīng)失敗。到這一步,我們便完成了爬取網(wǎng)頁信息的工作,接下來就是從這些網(wǎng)頁代碼里分析和獲取有用信息。
如何從網(wǎng)頁源碼中獲取有用的信息?
這里我們會用到re模塊的兩個(gè)方法,一個(gè)是re.findall( 模式(正則表達(dá)式), 目標(biāo)字符串),返回值為list類型,另一個(gè)是re.sub(要替換的字符,替換后字符,目標(biāo)字符串,替換個(gè)數(shù)),返回值為str類型。re.findall函數(shù)是通過指定的正則表達(dá)式來匹配出需要的HTML源碼,一般情況下是匹配源碼中的div容器,也就是類似“<div></div>“的標(biāo)簽語言。之后將匹配出的源碼用re.sub函數(shù)在進(jìn)一步替換處理,以此來篩選出我們需要的信息。下面結(jié)合代碼更直觀的理解一下
import reresponse = """<div class="c-span18 c-span-last"><em>太陽</em>是<em>太陽</em>系的中心天體,占有<em>太陽</em>系總體質(zhì)量的99.86%。 </div>""" partten = r'<div class="c-span18 c-span-last">([sS]*?)</div>' data = re.findall(partten, response,) print(data) data_clean = re.sub(r'<em>|</em>', '', data[0]) print(data_clean)輸出結(jié)果為
['<em>太陽</em>是<em>太陽</em> 系的中心天體,占有<em>太陽</em>系總體質(zhì)量的99.86%。'] 太陽是太陽系的中心天體,占有太陽系總體質(zhì)量的99.86%。第一行是findall函數(shù)的輸出結(jié)果。從內(nèi)容上看,我們已經(jīng)獲取了div容器里的內(nèi)容,但是很明顯,這里面摻雜著其他的標(biāo)記語言<em>和</em>。于是第二步sub函數(shù)將其中的<em>和</em>標(biāo)簽替換成了空字符串。這行輸出結(jié)果便是我們所需要的有用信息。
下面我們來嘗試爬取京東官網(wǎng)的手機(jī)圖片,以下是源碼
import urllib.request import re from fake_useragent import UserAgent import requests from requests.exceptions import ReadTimeout import osuser_agent = UserAgent() headers = {"User-Agent": user_agent.chrome,} def get_html(url, req=None):if req:url = url + reqelse:url = urltry:response = requests.get(url, headers=headers)if response.status_code == 200:#print(response.text)return response.textreturn 404except ReadTimeout:print('timeout404')except Exception as e:print(e)def get_request(response):if response == 404:return '服務(wù)器響應(yīng)失敗!'else:try:partten = r'<img width="220" height="220" data-img="1" data-lazy-img="//(.+?.jpg)">'data = re.compile(partten).findall(response)return dataexcept IndexError:print('未搜到有用信息') def output(data):if not os.path.exists('texts'):os.mkdir('texts')for index, inf in enumerate(data):image_url = 'https://' + infimage_byte = requests.get(url=image_url, headers=headers).contentwith open("./texts/{}.jpg".format(index),'wb') as f:f.write(image_byte)print('n第{}張圖片已下載保存成功...'.format(index))print('n總共{}張圖片已成功下載至texts文件夾中'.format(len(data))) def main(req):url = 'https://list.jd.com/list.html?cat=9987,653,655&page='html = get_html(url, req)data = get_request(html)output(data)if __name__ == '__main__':req = input('請輸入要下載的頁碼: ')main(req)程序運(yùn)行之后,我們按照提示輸入頁碼,程序便開始下載圖片
下載完成之后,我們打開指定的文件夾查看一下效果
大功告成!
總結(jié)
以上是生活随笔為你收集整理的爬虫 404 try_无所不能的Python之爬虫那点事儿的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python如何从一个dataframe
- 下一篇: python sorted下标_全!Py