摘要:下面跟大家詳細(xì)分享一下寫(xiě)爬蟲(chóng)抓取靜態(tài)網(wǎng)站的全過(guò)程。而我們上面說(shuō)的元字符都代表一定的規(guī)則和占據(jù)一定的字符。
遇到的需求
前段時(shí)間需要快速做個(gè)靜態(tài)展示頁(yè)面,要求是響應(yīng)式和較美觀。由于時(shí)間較短,自己動(dòng)手寫(xiě)的話也有點(diǎn)麻煩,所以就打算上網(wǎng)找現(xiàn)成的。
中途找到了幾個(gè)頁(yè)面發(fā)現(xiàn)不錯(cuò),然后就開(kāi)始思考怎么把頁(yè)面給下載下來(lái)。
由于之前還沒(méi)有了解過(guò)爬蟲(chóng),自然也就沒(méi)有想到可以用爬蟲(chóng)來(lái)抓取網(wǎng)頁(yè)內(nèi)容。所以我采取的辦法是:
打開(kāi)chrome的控制臺(tái),進(jìn)入Application選項(xiàng)
找到Frames選項(xiàng),找到html文件,再右鍵Save As...
手動(dòng)創(chuàng)建本地的js/css/images目錄
依次打開(kāi)Frames選項(xiàng)下的Images/Scripts/Stylesheets,一個(gè)文件就要右鍵Save As...
這個(gè)辦法是我當(dāng)時(shí)能想到的最好辦法了。不過(guò)這種人為的辦法有以下缺點(diǎn):
手工操作,麻煩費(fèi)時(shí)
一不小心就忘記保存哪個(gè)文件
難以處理路徑之間的關(guān)系,比如一張圖片a.jpg, 它在html中的引用方式是images/banner/a.jpg,這樣我們以后還要手動(dòng)去解決路徑依賴關(guān)系
然后剛好前段時(shí)間接觸了一點(diǎn)python,想到可以寫(xiě)個(gè)python爬蟲(chóng)來(lái)幫我自動(dòng)抓取靜態(tài)網(wǎng)站。于是就馬上動(dòng)手,參考相關(guān)資料等等。
下面跟大家詳細(xì)分享一下寫(xiě)爬蟲(chóng)抓取靜態(tài)網(wǎng)站的全過(guò)程。
前置知識(shí)儲(chǔ)備在下面的代碼實(shí)踐中,用到了python知識(shí)、正則表達(dá)式等等,核心技術(shù)是正則表達(dá)式。
我們來(lái)一一了解一下。
Python基礎(chǔ)知識(shí)如果你之前有過(guò)其他語(yǔ)言的學(xué)習(xí)經(jīng)歷,相信你可以很快上手python這門(mén)語(yǔ)言。具體學(xué)習(xí)可以上查看python官方文檔或者其他教程。
爬蟲(chóng)的概念爬蟲(chóng),按照我的理解,其實(shí)是一段自動(dòng)執(zhí)行的計(jì)算機(jī)程序,在web領(lǐng)域中,它存在的前提是模擬用戶在瀏覽器中的行為。
它的原理就是模擬用戶訪問(wèn)web網(wǎng)頁(yè),獲取網(wǎng)頁(yè)內(nèi)容,然后分析網(wǎng)頁(yè)內(nèi)容,找出我們感興趣的部分,并且最后處理數(shù)據(jù)。
流程圖是:
現(xiàn)在流行的爬蟲(chóng)主流實(shí)現(xiàn)形式有以下幾種:
自己抓取網(wǎng)頁(yè)內(nèi)容,然后自己實(shí)現(xiàn)分析過(guò)程
用別人寫(xiě)好的爬蟲(chóng)框架,比如Scrapy
正則表達(dá)式 概念正則表達(dá)式是由一系列元字符和普通字符組成的字符串,它的作用是根據(jù)一定的規(guī)則來(lái)匹配文本,最終可以對(duì)文本做出一系列的處理。
元字符是正則表達(dá)式中的保留字符,它有特殊的匹配規(guī)則,比如*代表匹配0到無(wú)窮多次,普通字符就是普通的abcd等等。
比如在前端中,常見(jiàn)的一個(gè)操作就是判斷用戶的輸入是否為空,這時(shí)候我們可以先通過(guò)正則表達(dá)式來(lái)進(jìn)行匹配,先過(guò)濾掉用戶輸入的兩邊空白值,具體實(shí)現(xiàn)如下:
function trim(value) { return value.replace(/^s+|s+$/g, "") } // 輸出 => "Python爬蟲(chóng)" trim(" Python爬蟲(chóng) ");
下面我們一起來(lái)具體了解一下正則表達(dá)式中的元字符。
正則表達(dá)式中的元字符在上面,我們說(shuō)過(guò)元字符是正則表達(dá)式中的保留字符,它有特殊的匹配規(guī)則,所以我們首先要了解經(jīng)常出現(xiàn)的元字符。
.代表匹配一個(gè)任意字符,除了 (換行符),比如可以匹配任意的字母數(shù)字等等
[...]表示字符組,里面可以有任意字符,它只會(huì)匹配當(dāng)中的任意一個(gè),比如[abc]可以匹配a或b或c,這里值得注意的是,字符組里面的元字符有時(shí)候會(huì)被當(dāng)成是普通字符,比如[-*?]等等,它代表的僅僅是-或*或?,而不是-代表區(qū)間,*代表0到無(wú)窮次匹配,?代表0或1次匹配。
[^...]跟[...]的含義相反,它的意思是匹配一個(gè)不屬于[...]里面的字符,而不是不匹配[...]里面的字符,這兩種說(shuō)法雖然細(xì)微但是有很大差別,前者規(guī)定一定要匹配一個(gè)字符,這個(gè)切記。
例子:[^123]可以匹配4/5/6等等,但是不匹配1/2/3
*代表匹配0次到無(wú)窮次,可以不匹配任何字符
+代表匹配1次到無(wú)窮次,至少匹配1次
?代表匹配0次或1次
{min, max}代表匹配min次到max次,如a{3, 5}表示a至少匹配3-5次
^代表匹配字符串開(kāi)頭,如^a表示a要出現(xiàn)在字符串開(kāi)頭,bcd則不匹配
$代表匹配字符串結(jié)尾, 如A$表示A要出現(xiàn)在字符串結(jié)尾,ABAB則不匹配
|代表一個(gè)范圍,可以匹配任意的子表達(dá)式,比如abc|def可以匹配abc或者def,不匹配abd
(...)代表分組,它的作用有界定子表達(dá)式的范圍和與提供功能的元字符相結(jié)合,比如(abc|def)+代表可以匹配1次或1次以上的abc或者defdef,如abcabcabc,def
i代表反向引用,i可以為1/2/3等整數(shù),它的含義是指向上一個(gè)()里面匹配的內(nèi)容。比如匹配(abc)+(12)*12,如果匹配成功的話,1的內(nèi)容是abc,2的內(nèi)容是12或者空。反向引用通常用在匹配""或者""中
環(huán)視我理解的環(huán)視是界定當(dāng)前匹配子表達(dá)式的左邊文本和右邊文本出現(xiàn)的情況,環(huán)視本身不會(huì)占據(jù)匹配的字符,它是當(dāng)前子表達(dá)式的匹配規(guī)則但是本身不算進(jìn)匹配文本。而我們上面說(shuō)的元字符都代表一定的規(guī)則和占據(jù)一定的字符。環(huán)視可分為四種:肯定順序環(huán)視、否定順序環(huán)視、肯定逆序環(huán)視和否定逆序環(huán)視。它們的工作流程如下:
肯定順序環(huán)視:先找到環(huán)視中的文本在右側(cè)出現(xiàn)的初始位置,然后從匹配到的右側(cè)文本的最左的位置開(kāi)始匹配字符
否定順序環(huán)視:先找到環(huán)視中的文本在右側(cè)沒(méi)有出現(xiàn)的初始位置,然后從匹配到的右側(cè)文本的最左的位置開(kāi)始匹配字符
肯定逆序環(huán)視:先找到環(huán)視中的文本在左側(cè)出現(xiàn)的初始位置,然后從匹配到的左側(cè)文本的最右的位置開(kāi)始匹配字符
否定逆序環(huán)視:先找到環(huán)視中的文本在左側(cè)沒(méi)有出現(xiàn)的初始位置,然后從匹配到的左側(cè)文本的最右的位置開(kāi)始匹配字符
肯定順序環(huán)視匹配成功的條件是當(dāng)前的子表達(dá)式能夠匹配右側(cè)文本,它的寫(xiě)法是(?=...),...代表要環(huán)視的內(nèi)容。比如正則表達(dá)式(?=hello)he的意思是匹配包含hello的文本,它只匹配位置,不匹配具體字符,匹配到位置之后,才真正匹配要占用的字符是he,所以后面可以具體匹配llo等。
對(duì)于(?=hello)he而言,hello world可以匹配成功,而hell world則匹配失敗。具體代碼如下:
import re reg1 = r"(?=hello)he" print(re.search(reg1, "hello world")) print(re.search(reg1, "hell world hello")) print(re.search(reg1, "hell world")) # 輸出結(jié)果 <_sre.SRE_Match object; span=(0, 2), match="he"> <_sre.SRE_Match object; span=(11, 13), match="he"> None
否定順序環(huán)視匹配成功的條件是當(dāng)前的子表達(dá)式不能匹配右側(cè)文本,它的寫(xiě)法是(?!...),...代表要環(huán)視的內(nèi)容,還是上面的例子,比如正則表達(dá)式(?!hello)he的意思是匹配不是hello的文本,找到位置,然后匹配he。
例子如下:
import re reg2 = r"(?!hello)he" print(re.search(reg2, "hello world")) print(re.search(reg2, "hell world hello")) print(re.search(reg2, "hell world")) # 輸出結(jié)果 None <_sre.SRE_Match object; span=(0, 2), match="he"> <_sre.SRE_Match object; span=(0, 2), match="he">
肯定逆序環(huán)視匹配成功的條件是當(dāng)前的子表達(dá)式能夠匹配左側(cè)文本,它的寫(xiě)法是(?<=...),...代表要環(huán)視的內(nèi)容,比如正則表達(dá)式(?<=hello)-python的意思是匹配包含-python的子表達(dá)式,并且它的左側(cè)必須出現(xiàn)hello,hello只匹配位置,不匹配具體字符,真正占用的字符是后面的-python。
例子如下:
import re reg3 = r"(?<=hello)-python" print(re.search(reg3, "hello-python")) print(re.search(reg3, "hell-python hello-python")) print(re.search(reg3, "hell-python")) # 輸出結(jié)果 <_sre.SRE_Match object; span=(5, 12), match="-python"> <_sre.SRE_Match object; span=(17, 24), match="-python"> None
否定逆序環(huán)視匹配成功的條件是當(dāng)前的子表達(dá)式不能匹配左側(cè)文本,它的寫(xiě)法是(?,...代表要環(huán)視的內(nèi)容,比如正則表達(dá)式(?的意思是匹配包含-python的子表達(dá)式,并且它的左側(cè)必須不能出現(xiàn)hello。
例子如下:
import re reg4 = r"(? <_sre.SRE_Match object; span=(4, 11), match="-python">
環(huán)視在對(duì)字符串插入某些字符很有效,你可以利用它來(lái)匹配位置,然后插入對(duì)應(yīng)的字符,而不需要對(duì)原來(lái)的文本進(jìn)行替換。
捕獲分組在正則表達(dá)式中,分組可以幫助我們提取出想要的特定信息。
指明分組很簡(jiǎn)單,只需要在想捕獲的表達(dá)式中兩端加上()就可以了。在python中,我們可以用re.search(reg, xx).groups()來(lái)獲取到所有的分組。
默認(rèn)的()中都指明了一個(gè)分組,分組序號(hào)為i,i從1開(kāi)始,分別用re.search(reg, xx).group(i)來(lái)獲取。
如果不想捕獲分組可以使用(?:...)來(lái)指明。
具體例子如下:
import re reg7 = r"hello,([a-zA-Z0-9]+)" print(re.search(reg7, "hello,world").groups()) print(re.search(reg7, "hello,world").group(1)) print(re.search(reg7, "hello,python").groups()) print(re.search(reg7, "hello,python").group(1)) # 輸出結(jié)果 ("world",) world ("python",) python貪婪匹配
貪婪匹配是指正則表達(dá)式盡可能匹配多的字符,也就是趨于最大長(zhǎng)度匹配。
正則表達(dá)式默認(rèn)是貪婪模式。
例子如下:
import re reg5 = r"hello.*world" print(re.search(reg5, "hello world,hello python,hello world,hello javascript")) # 輸出結(jié)果 <_sre.SRE_Match object; span=(0, 36), match="hello world,hello python,hello world">
由上可以看到它匹配的是hello world,hello python,hello world而不是剛開(kāi)始的hello world。那如果我們只是想匹配剛開(kāi)始的hello world,這時(shí)候我們可以利用正則表達(dá)式的非貪婪模式。
非貪婪匹配正好與貪婪匹配相反,它是指盡可能匹配少的字符,只要匹配到了就結(jié)束。要使用貪婪模式,僅需要在量詞后面加上一個(gè)問(wèn)號(hào)(?)就可以。
還是剛剛那個(gè)例子:
import re reg5 = r"hello.*world" reg6 = r"hello.*?world" print(re.search(reg5, "hello world,hello python,hello world,hello javascript")) print(re.search(reg6, "hello world,hello python,hello world,hello javascript")) # 輸出結(jié)果 <_sre.SRE_Match object; span=(0, 36), match="hello world,hello python,hello world"> <_sre.SRE_Match object; span=(0, 11), match="hello world">
由上可以看到這是我們剛剛想要匹配的效果。
進(jìn)入開(kāi)發(fā)有了上面的基礎(chǔ)知識(shí),我們就可以進(jìn)入開(kāi)發(fā)環(huán)節(jié)了。
我們想實(shí)現(xiàn)的最終效果本次我們的最終目的是寫(xiě)一個(gè)簡(jiǎn)單的python爬蟲(chóng),這個(gè)爬蟲(chóng)能夠下載一個(gè)靜態(tài)網(wǎng)頁(yè),并且在保持網(wǎng)頁(yè)引用資源的相對(duì)路徑下下載它的靜態(tài)資源(如js/css/images)。測(cè)試網(wǎng)站為http://www.peersafe.cn/index.html,效果圖如下:
開(kāi)發(fā)流程我們的總體思路是先獲取到網(wǎng)頁(yè)的內(nèi)容,然后利用正則表達(dá)式來(lái)提取我們想要的資源鏈接,最后就是下載資源。
獲取網(wǎng)頁(yè)內(nèi)容我們選用python3自帶的urllib.http來(lái)發(fā)出http請(qǐng)求,或者你可以采用第三方請(qǐng)求庫(kù)requests。
獲取內(nèi)容的部分代碼如下:
url = "http://www.peersafe.cn/index.html" # 讀取網(wǎng)頁(yè)內(nèi)容 webPage = urllib.request.urlopen(url) data = webPage.read() content = data.decode("UTF-8") print("> 網(wǎng)站內(nèi)容抓取完畢,內(nèi)容長(zhǎng)度:", len(content))
獲取到內(nèi)容之后,我們需要把它保存下來(lái),也就是寫(xiě)到本地磁盤(pán)上。我們定義一個(gè)SAVE_PATH路徑,代表專(zhuān)門(mén)放置爬蟲(chóng)下載的文件。
# python-spider-downloads是我們要放置的目錄 # 這里推薦使用os模塊來(lái)獲取當(dāng)前的目錄或者拼接路徑 # 不推薦直接使用"F://xxx" + "http://python-spider-downloads"等方式 SAVE_PATH = os.path.join(os.path.abspath("."), "python-spider-downloads")
接下來(lái)就是為這個(gè)站點(diǎn)創(chuàng)建一個(gè)多帶帶的文件夾了。這個(gè)站點(diǎn)文件夾的格式是xxxx-xx-xx-domain,比如2018-08-03-www.peersafe.cn。在此之前,我們需要寫(xiě)一個(gè)函數(shù)來(lái)提取出一個(gè)url鏈接的域名、相對(duì)路徑、請(qǐng)求文件名和請(qǐng)求參數(shù)等等,這個(gè)在后續(xù)在根據(jù)資源文件的引用方式創(chuàng)建相對(duì)應(yīng)的文件夾時(shí)也會(huì)用到。
比如輸入http://www.peersafe.cn/index.html,那么將會(huì)輸出:
{"baseUrl": "http://www.peersafe.cn", "fullPath": "http://www.peersafe.cn/", "protocol": "http://", "domain ": "www.peersafe.cn", "path": "/", "fileName": "index.html", "ext": "html", "params": ""}
部分代碼如下:
REG_URL = r"^(https?://|//)?((?:[a-zA-Z0-9-_]+.)+(?:[a-zA-Z0-9-_:]+))((?:/[-_.a-zA-Z0-9]*?)*)((?<=/)[-a-zA-Z0-9]+(?:.([a-zA-Z0-9]+))+)?((?:?[a-zA-Z0-9%&=]*)*)$" regUrl = re.compile(REG_URL) # ... """ 解析URL地址 """ def parseUrl(url): if not url: return res = regUrl.search(url) # 在這里,我們把192.168.1.109:8080的形式也解析成域名domain,實(shí)際過(guò)程中www.baidu.com等才是域名,192.168.1.109只是IP地址 # ("http://", "192.168.1.109:8080", "/abc/images/111/", "index.html", "html", "?a=1&b=2") if res is not None: path = res.group(3) fullPath = res.group(1) + res.group(2) + res.group(3) if not path.endswith("/"): path = path + "/" fullPath = fullPath + "/" return dict( baseUrl=res.group(1) + res.group(2), fullPath=fullPath, protocol=res.group(1), domain=res.group(2), path=path, fileName=res.group(4), ext=res.group(5), params=res.group(6) ) """ 解析路徑 eg: basePath => F:Programspythonpython-spider-downloads resourcePath => /a/b/c/ or a/b/c return => F:Programspythonpython-spider-downloadsac """ def resolvePath(basePath, resourcePath): # 解析資源路徑 res = resourcePath.split("/") # 去掉空目錄 /a/b/c/ => [a, b, c] dirList = list(filter(lambda x: x, res)) # 目錄不為空 if dirList: # 拼接出絕對(duì)路徑 resourcePath = reduce(lambda x, y: os.path.join(x, y), dirList) dirStr = os.path.join(basePath, resourcePath) else: dirStr = basePath return dirStr
上面的正則表達(dá)式REG_URL有點(diǎn)長(zhǎng),這個(gè)正則表達(dá)式能解析目前我遇到的各種url形式,如果有不能解析的,你可以自行補(bǔ)充,我測(cè)試過(guò)的url列表可以去我的github中查看。
首先一個(gè)最復(fù)雜的url鏈接(比如"http://192.168.1.109:8080/abc/images/111/index.html?a=1&b=2")來(lái)說(shuō),我們想分別提取出http://, 192.168.1.109:8080, /abc/images/111/, index.html, ?a=1&b=2。提取出/abc/images/111/的目的是為以后創(chuàng)建目錄做準(zhǔn)備,index.html是寫(xiě)入網(wǎng)頁(yè)內(nèi)容的名字。
有需要的可以深入研究一下REG_URL的寫(xiě)法,如果有更好的或者看不懂的,我們可以一起探討。
有了parseUrl函數(shù)之后,我們就可以把剛剛獲取網(wǎng)頁(yè)內(nèi)容和寫(xiě)入文件聯(lián)系起來(lái)了,代碼如下:
# 首先創(chuàng)建這個(gè)站點(diǎn)的文件夾 urlDict = parseUrl(url) print("分析的域名:", urlDict) domain = urlDict["domain"] filePath = time.strftime("%Y-%m-%d", time.localtime()) + "-" + domain # 如果是192.168.1.1:8000等形式,變成192.168.1.1-8000,:不可以出現(xiàn)在文件名中 filePath = re.sub(r":", "-", filePath) SAVE_PATH = os.path.join(SAVE_PATH, filePath) # 讀取網(wǎng)頁(yè)內(nèi)容 webPage = urllib.request.urlopen(url) data = webPage.read() content = data.decode("UTF-8") print("> 網(wǎng)站內(nèi)容抓取完畢,內(nèi)容長(zhǎng)度:", len(content)) # 把網(wǎng)站的內(nèi)容寫(xiě)下來(lái) pageName = "" if urlDict["fileName"] is None: pageName = "index.html" else: pageName = urlDict["fileName"] pageIndexDir = resolvePath(SAVE_PATH, urlDict["path"]) if not os.path.exists(pageIndexDir): os.makedirs(pageIndexDir) pageIndexPath = os.path.join(pageIndexDir, pageName) print("主頁(yè)的地址:", pageIndexPath) f = open(pageIndexPath, "wb") f.write(data) f.close()提取有用的資源鏈接
我們想要的資源是圖片資源,js文件、css文件和字體文件。如果我們要對(duì)網(wǎng)頁(yè)內(nèi)容一一進(jìn)行解析,利用分組,來(lái)捕獲出我們想要的鏈接形式,比如images/1.png和scripts/lib/jquery.min.js。
代碼如下:
REG_RESOURCE_TYPE = r"(?:href|src|data-original|data-src)=[""](.+?.(?:js|css|jpg|jpeg|png|gif|svg|ico|ttf|woff2))[a-zA-Z0-9?=.]*[""]" # re.S代表開(kāi)啟多行匹配模式 regResouce = re.compile(REG_RESOURCE_TYPE, re.S) # ... # 解析網(wǎng)頁(yè)內(nèi)容,獲取有效的鏈接 # content是上一步讀取到的網(wǎng)頁(yè)內(nèi)容 contentList = re.split(r"s+", content) resourceList = [] for line in contentList: resList = regResouce.findall(line) if resList is not None: resourceList = resourceList + resList下載資源
在解析出資源鏈接后,我們要針對(duì)每一個(gè)資源鏈接進(jìn)行檢查,把它變成符合http請(qǐng)求的url格式,比如把images/1.png加上http頭和剛剛的domain,也就是http://domain/images/1.png。
下面是對(duì)資源鏈接進(jìn)行處理的代碼:
# ./static/js/index.js # /static/js/index.js # static/js/index.js # //abc.cc/static/js # http://www.baidu/com/static/index.js if resourceUrl.startswith("./"): resourceUrl = urlDict["fullPath"] + resourceUrl[1:] elif resourceUrl.startswith("http://"): resourceUrl = "https:" + resourceUrl elif resourceUrl.startswith("/"): resourceUrl = urlDict["baseUrl"] + resourceUrl elif resourceUrl.startswith("http") or resourceUrl.startswith("https"): # 不處理,這是我們想要的url格式 pass elif not (resourceUrl.startswith("http") or resourceUrl.startswith("https")): # static/js/index.js這種情況 resourceUrl = urlDict["fullPath"] + resourceUrl else: print("> 未知resource url: %s" % resourceUrl)
接著就是對(duì)每個(gè)規(guī)范的資源鏈接進(jìn)行解析(parseUrl),提取出它要存放的目錄和文件名等等,然后創(chuàng)建對(duì)應(yīng)的目錄。
在這里,我也處理了引用的其他網(wǎng)站的資源。
# 解析文件,查看文件路徑 resourceUrlDict = parseUrl(resourceUrl) if resourceUrlDict is None: print("> 解析文件出錯(cuò):%s" % resourceUrl) continue resourceDomain = resourceUrlDict["domain"] resourcePath = resourceUrlDict["path"] resourceName = resourceUrlDict["fileName"] if resourceDomain != domain: print("> 該資源不是本網(wǎng)站的,也下載:", resourceDomain) # 如果下載的話,根目錄就要變了 # 再創(chuàng)建一個(gè)目錄,用于保存其他地方的資源 resourceDomain = re.sub(r":", "-", resourceDomain) savePath = os.path.join(SAVE_PATH, resourceDomain) if not os.path.exists(SAVE_PATH): print("> 目標(biāo)目錄不存在,創(chuàng)建:", savePath) os.makedirs(savePath) # continue else: savePath = SAVE_PATH # 解析資源路徑 dirStr = resolvePath(savePath, resourcePath) if not os.path.exists(dirStr): print("> 目標(biāo)目錄不存在,創(chuàng)建:", dirStr) os.makedirs(dirStr) # 寫(xiě)入文件 downloadFile(resourceUrl, os.path.join(dirStr, resourceName))
下載的函數(shù)downloadFile的代碼是:
""" 下載文件 """ def downloadFile(srcPath, distPath): global downloadedList if distPath in downloadedList: return try: response = urllib.request.urlopen(srcPath) if response is None or response.status != 200: return print("> 請(qǐng)求異常:", srcPath) data = response.read() f = open(distPath, "wb") f.write(data) f.close() downloadedList.append(distPath) # print(">>>: " + srcPath + ":下載成功") except Exception as e: print("報(bào)錯(cuò)了:", e)
以上就是我們的開(kāi)發(fā)全過(guò)程。
知識(shí)總結(jié) 本次開(kāi)發(fā)用到的技術(shù)利用urllib.http來(lái)發(fā)網(wǎng)絡(luò)請(qǐng)求
利用正則表達(dá)式來(lái)解析資源鏈接
利用os系統(tǒng)模塊來(lái)處理文件路徑問(wèn)題
心得體會(huì)這篇文章也算是我這段時(shí)間學(xué)習(xí)python的一個(gè)實(shí)踐總結(jié),順便記錄下正則表達(dá)式的知識(shí)。同時(shí)我也希望能夠幫助到那些想學(xué)習(xí)正則表達(dá)式和爬蟲(chóng)的小伙伴。
該python爬蟲(chóng)的源代碼已經(jīng)放在我的github上,有興趣的小伙伴可以上去看看,滿意的可以順便給個(gè)Star,感謝支持。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/42119.html
摘要:通用網(wǎng)絡(luò)爬蟲(chóng)通用網(wǎng)絡(luò)爬蟲(chóng)又稱(chēng)全網(wǎng)爬蟲(chóng),爬取對(duì)象從一些種子擴(kuò)充到整個(gè)。為提高工作效率,通用網(wǎng)絡(luò)爬蟲(chóng)會(huì)采取一定的爬取策略。介紹是一個(gè)國(guó)人編寫(xiě)的強(qiáng)大的網(wǎng)絡(luò)爬蟲(chóng)系統(tǒng)并帶有強(qiáng)大的。 爬蟲(chóng) 簡(jiǎn)單的說(shuō)網(wǎng)絡(luò)爬蟲(chóng)(Web crawler)也叫做網(wǎng)絡(luò)鏟(Web scraper)、網(wǎng)絡(luò)蜘蛛(Web spider),其行為一般是先爬到對(duì)應(yīng)的網(wǎng)頁(yè)上,再把需要的信息鏟下來(lái)。 分類(lèi) 網(wǎng)絡(luò)爬蟲(chóng)按照系統(tǒng)結(jié)構(gòu)和實(shí)現(xiàn)技術(shù),...
摘要:通用網(wǎng)絡(luò)爬蟲(chóng)通用網(wǎng)絡(luò)爬蟲(chóng)又稱(chēng)全網(wǎng)爬蟲(chóng),爬取對(duì)象從一些種子擴(kuò)充到整個(gè)。為提高工作效率,通用網(wǎng)絡(luò)爬蟲(chóng)會(huì)采取一定的爬取策略。介紹是一個(gè)國(guó)人編寫(xiě)的強(qiáng)大的網(wǎng)絡(luò)爬蟲(chóng)系統(tǒng)并帶有強(qiáng)大的。 爬蟲(chóng) 簡(jiǎn)單的說(shuō)網(wǎng)絡(luò)爬蟲(chóng)(Web crawler)也叫做網(wǎng)絡(luò)鏟(Web scraper)、網(wǎng)絡(luò)蜘蛛(Web spider),其行為一般是先爬到對(duì)應(yīng)的網(wǎng)頁(yè)上,再把需要的信息鏟下來(lái)。 分類(lèi) 網(wǎng)絡(luò)爬蟲(chóng)按照系統(tǒng)結(jié)構(gòu)和實(shí)現(xiàn)技術(shù),...
摘要:以下這些項(xiàng)目,你拿來(lái)學(xué)習(xí)學(xué)習(xí)練練手。當(dāng)你每個(gè)步驟都能做到很優(yōu)秀的時(shí)候,你應(yīng)該考慮如何組合這四個(gè)步驟,使你的爬蟲(chóng)達(dá)到效率最高,也就是所謂的爬蟲(chóng)策略問(wèn)題,爬蟲(chóng)策略學(xué)習(xí)不是一朝一夕的事情,建議多看看一些比較優(yōu)秀的爬蟲(chóng)的設(shè)計(jì)方案,比如說(shuō)。 (一)如何學(xué)習(xí)Python 學(xué)習(xí)Python大致可以分為以下幾個(gè)階段: 1.剛上手的時(shí)候肯定是先過(guò)一遍Python最基本的知識(shí),比如說(shuō):變量、數(shù)據(jù)結(jié)構(gòu)、語(yǔ)法...
從行業(yè)角度來(lái)說(shuō),通過(guò)一步一步剖析,目標(biāo)就是簡(jiǎn)易,新手入門(mén)requests網(wǎng)絡(luò)爬蟲(chóng)及新手入門(mén)pandas數(shù)據(jù)剖析就能完成,文中關(guān)鍵為大家介紹Python網(wǎng)絡(luò)爬蟲(chóng)抓取金融衍生品數(shù)據(jù)庫(kù)的經(jīng)典案例,感興趣的小伙伴一起了解一下吧 哈嘍大家好政胤今日教給大家抓取金融衍生品數(shù)據(jù)和信息 每日任務(wù)介紹 最先,顧客原消費(fèi)是獲得https://hq.smm.cn/copper網(wǎng)站里的價(jià)錢(qián)數(shù)據(jù)和信息(注:獲得的...
摘要:在這之前,還是有必要對(duì)一些概念超輕量級(jí)反爬蟲(chóng)方案后端掘金前言爬蟲(chóng)和反爬蟲(chóng)日益成為每家公司的標(biāo)配系統(tǒng)。 爬蟲(chóng)修煉之道——從網(wǎng)頁(yè)中提取結(jié)構(gòu)化數(shù)據(jù)并保存(以爬取糗百文本板塊所有糗事為例) - 后端 - 掘金歡迎大家關(guān)注我的專(zhuān)題:爬蟲(chóng)修煉之道 上篇 爬蟲(chóng)修煉之道——編寫(xiě)一個(gè)爬取多頁(yè)面的網(wǎng)絡(luò)爬蟲(chóng)主要講解了如何使用python編寫(xiě)一個(gè)可以下載多頁(yè)面的爬蟲(chóng),如何將相對(duì)URL轉(zhuǎn)為絕對(duì)URL,如何限速,...
閱讀 1164·2021-10-14 09:43
閱讀 1222·2021-10-11 11:07
閱讀 3163·2021-08-18 10:23
閱讀 1540·2019-08-29 16:18
閱讀 1057·2019-08-28 18:21
閱讀 1538·2019-08-26 12:12
閱讀 3826·2019-08-26 10:11
閱讀 2566·2019-08-23 18:04