目錄
- 前言
- 一、簡(jiǎn)單靜態(tài)網(wǎng)頁(yè)的爬取
- 1.1 選取爬蟲(chóng)策略——縮略圖
- 1.2 選取爬蟲(chóng)策略——高清大圖
- 二、動(dòng)態(tài)加載網(wǎng)站的爬取
- 2.1 選取爬蟲(chóng)策略——selenium
- 2.2 選取爬蟲(chóng)策略——api
- 三、selenium模擬登錄
前言
python基礎(chǔ)爬蟲(chóng)主要針對(duì)一些反爬機(jī)制較為簡(jiǎn)單的網(wǎng)站,是對(duì)爬蟲(chóng)整個(gè)過(guò)程的了解與爬蟲(chóng)策略的熟練過(guò)程。
爬蟲(chóng)分為四個(gè)步驟:請(qǐng)求,解析數(shù)據(jù),提取數(shù)據(jù),存儲(chǔ)數(shù)據(jù)。本文也會(huì)從這四個(gè)角度介紹基礎(chǔ)爬蟲(chóng)的案例。
一、簡(jiǎn)單靜態(tài)網(wǎng)頁(yè)的爬取
我們要爬取的是一個(gè)壁紙網(wǎng)站的所有壁紙
http://www.netbian.com/dongman/
![](/d/20211017/70ce1f04683d438a9be369d187200e14.gif)
1.1 選取爬蟲(chóng)策略——縮略圖
首先打開(kāi)開(kāi)發(fā)者模式,觀察網(wǎng)頁(yè)結(jié)構(gòu),找到每一張圖對(duì)應(yīng)的的圖片標(biāo)簽,可以發(fā)現(xiàn)我們只要獲取到標(biāo)黃的img標(biāo)簽并向它發(fā)送請(qǐng)求就可以得到壁紙的預(yù)覽圖了。
![](/d/20211017/9074190c397eb81b7e794fa0324a00bd.gif)
隨后注意到網(wǎng)站不止一頁(yè),打開(kāi)前3頁(yè)的網(wǎng)站觀察url有沒(méi)有規(guī)律
http://www.netbian.com/dongman/index.htm#第一頁(yè)
http://www.netbian.com/dongman/index_2.htm#第二頁(yè)
http://www.netbian.com/dongman/index_3.htm#第三頁(yè)
我們發(fā)現(xiàn)除了第一頁(yè)其他頁(yè)數(shù)的url都是有著固定規(guī)律的,所以先構(gòu)建一個(gè)含有所有頁(yè)數(shù)url的列表
url_start = 'http://www.netbian.com/dongman/'
url_list=['http://www.netbian.com/dongman/index.htm']
if not os.path.exists('./exercise'):
os.mkdir('./exercise')
for i in range(2,133):
url = url_start+'index_'+str(i)+'.htm'
url_list.append(url)
至此我們的基本爬蟲(chóng)策略就確定了。
網(wǎng)頁(yè)請(qǐng)求
for url in url_list:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
}
response = requests.get(url=url,headers=headers).text
解析數(shù)據(jù)
在這里我們選用etree解析數(shù)據(jù)
tree = etree.HTML(response)
提取數(shù)據(jù)
在這里我們選用xpath提取數(shù)據(jù)
leaf = tree.xpath('//div[@class="list"]//ul/li/a/img/@src')
for l in leaf:
print(l)
h = requests.get(url=l, headers=headers).content
存儲(chǔ)數(shù)據(jù)
i = 'exercise/' + l.split('/')[-1]
with open(i, 'wb') as fp:
fp.write(h)
完整代碼
import requests
from lxml import etree
import os
url_start = 'http://www.netbian.com/dongman/'
url_list=['http://www.netbian.com/dongman/index.htm']
#http://www.netbian.com/dongman/index_2.htm
if not os.path.exists('./exercise'):
os.mkdir('./exercise')
for i in range(2,133):
url = url_start+'index_'+str(i)+'.htm'
url_list.append(url)
print(url_list)
for url in url_list:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
}
response = requests.get(url=url,headers=headers).text
tree = etree.HTML(response)
leaf = tree.xpath('//div[@class="list"]//ul/li/a/img/@src')
for l in leaf:
print(l)
h = requests.get(url=l, headers=headers).content
i = 'exercise/' + l.split('/')[-1]
with open(i, 'wb') as fp:
fp.write(h)
1.2 選取爬蟲(chóng)策略——高清大圖
在剛剛的爬蟲(chóng)中我們爬取到的只是壁紙的縮略圖,要想爬到高清版本,就需要我們更改策略。重新打開(kāi)開(kāi)發(fā)者工具進(jìn)行觀察,發(fā)現(xiàn)在原先爬取的img標(biāo)簽之上還有一個(gè)href標(biāo)簽,打開(kāi)之后就會(huì)跳轉(zhuǎn)高清大圖。
![](/d/20211017/b30be24084edaeb72f162c20ac2dfa47.gif)
![](/d/20211017/92995104dcb9fda59998cc05958a8303.gif)
那么此時(shí)我們的爬取策略就變成了提取這個(gè)href標(biāo)簽的內(nèi)容,向這個(gè)標(biāo)簽中的網(wǎng)站發(fā)送請(qǐng)求,隨后在該網(wǎng)站中找到img標(biāo)簽進(jìn)行再一次請(qǐng)求。
我們用到了正則表達(dá)式來(lái)提取href標(biāo)簽的內(nèi)容。正則表達(dá)式是比xpath語(yǔ)法更簡(jiǎn)便的一種數(shù)據(jù)提取方法,具體有關(guān)語(yǔ)法可查看以下文檔
for url in url_list:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
}
response = requests.get(url=url,headers=headers).text
leaf = re.findall("desk/\d*.htm",response,re.S)
for l in leaf:
url = "http://www.netbian.com/"+str(l)
h = requests.get(url=url, headers=headers).text
leaf_ =re.findall('div class="pic">.*?(http://img.netbian.com/file/\d*/\d*/\w*.jpg)',h,re.S)
這樣輸出的leaf_就是我們要找的高清大圖的img標(biāo)簽,此時(shí)我們只需要再次發(fā)送請(qǐng)求隨后再保存數(shù)據(jù)就可以了。
存儲(chǔ)數(shù)據(jù)
for l_ in leaf_:
print(l_)
h = requests.get(url=l_, headers=headers).content
i = 'exercise/' + l_.split('/')[-1]
with open(i, 'wb') as fp:
fp.write(h)
完整代碼
import requests
import os
import re
url_start = 'http://www.netbian.com/dongman/'
url_list=['http://www.netbian.com/dongman/index.htm']
if not os.path.exists('./exercise'):
os.mkdir('./exercise')
for i in range(2,133):
url = url_start+'index_'+str(i)+'.htm'
url_list.append(url)
print(url_list)
for url in url_list:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
}
response = requests.get(url=url,headers=headers).text
leaf = re.findall("desk/\d*.htm",response,re.S)
for l in leaf:
url = "http://www.netbian.com/"+str(l)
h = requests.get(url=url, headers=headers).text
leaf_ =re.findall('div class="pic">.*?(http://img.netbian.com/file/\d*/\d*/\w*.jpg)',h,re.S)
for l_ in leaf_:
print(l_)
h = requests.get(url=l_, headers=headers).content
i = 'exercise/' + l_.split('/')[-1]
with open(i, 'wb') as fp:
fp.write(h)
二、動(dòng)態(tài)加載網(wǎng)站的爬取
我們要爬取的是另一個(gè)壁紙網(wǎng)站的所有壁紙
https://sucai.gaoding.com/topic/9080?
![](/d/20211017/068a1680f4b41d6390eeb2a0ed348325.gif)
2.1 選取爬蟲(chóng)策略——selenium
首先打開(kāi)開(kāi)發(fā)者模式,觀察網(wǎng)頁(yè)結(jié)構(gòu),此時(shí)我們會(huì)發(fā)現(xiàn)一頁(yè)上的所有壁紙并不是全部都加載出來(lái)了的,也就是說(shuō)隨著我們下拉滾動(dòng)條,內(nèi)容會(huì)不斷實(shí)時(shí)加載出來(lái),查看網(wǎng)頁(yè)元素時(shí)也能看到lazy-image這個(gè)代表動(dòng)態(tài)加載的標(biāo)簽。
![](/d/20211017/3f6f8a6c35e256678b570ace9b5e1ceb.gif)
由于是動(dòng)態(tài)加載,因此不能用之前的直接發(fā)送請(qǐng)求的辦法來(lái)爬取數(shù)據(jù)了,面對(duì)這種情況我們就需要模擬瀏覽器發(fā)送一個(gè)請(qǐng)求,并且下拉頁(yè)面,來(lái)實(shí)現(xiàn)爬取一個(gè)實(shí)時(shí)加載網(wǎng)頁(yè)的目的。
觀察完網(wǎng)頁(yè)結(jié)構(gòu)之后我們又來(lái)觀察頁(yè)數(shù),這次就不多說(shuō)了,想必大家也能發(fā)現(xiàn)規(guī)律
url_list=[]
for i in range(1,4):
url = 'https://sucai.gaoding.com/topic/9080?p={}'.format(i)
url_list.append(url)
網(wǎng)頁(yè)請(qǐng)求
在這里我們用到了selenium這個(gè)自動(dòng)化測(cè)試框架
for url in url_list:
driver = webdriver.Chrome()
driver.get(url)
driver.maximize_window()
time.sleep(2)
i=0
while i10:#下拉滾動(dòng)條加載頁(yè)面
i+=1
driver.execute_script("window.scrollBy(0,500)")
driver.implicitly_wait(5)#顯式等待
解析提取數(shù)據(jù)
items = driver.find_elements_by_xpath("http://*[@class='gdd-lazy-image__img gdd-lazy-image__img--loaded']")
for item in items:
href = item.get_attribute('src')
print(href)
至于數(shù)據(jù)的存儲(chǔ)只需要再請(qǐng)求我們爬下來(lái)的href標(biāo)簽的網(wǎng)站就可以了。
完整代碼
from selenium import webdriver
import time
import os
if not os.path.exists('./exercise'):
os.mkdir('./exercise')
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.75 Safari/537.36'
}
url_list=[]
url_f_list=[]
for i in range(1,4):
url = 'https://sucai.gaoding.com/topic/9080?p={}'.format(i)
url_list.append(url)
for url in url_list:
driver = webdriver.Chrome()
driver.get(url)
driver.maximize_window()
time.sleep(2)
i=0
while i10:
i+=1
driver.execute_script("window.scrollBy(0,500)")
driver.implicitly_wait(5)#顯式等待
items = driver.find_elements_by_xpath("http://*[@class='gdd-lazy-image__img gdd-lazy-image__img--loaded']")
for item in items:
href = item.get_attribute('src')
print(href)
2.2 選取爬蟲(chóng)策略——api
眾所周知,api接口是個(gè)好東西,如果找到了它,我們就無(wú)需擔(dān)心動(dòng)態(tài)加載,請(qǐng)求api返回給我們的是json格式的字典,里面或許有我們需要的東西也說(shuō)不定。那么我們重新打開(kāi)開(kāi)發(fā)者工具搜索一番吧!
![](/d/20211017/62210f9e14853ad3fab3c7f33e7a3ce0.gif)
從Element切換到Network我們可以發(fā)現(xiàn)這里多了好多奇怪的東西,但是打開(kāi)preview好像沒(méi)有我們能用到的。
這個(gè)時(shí)候別灰心,切換下頁(yè)面,等第二頁(yè)加載出來(lái)的時(shí)候最后又多出來(lái)了一個(gè)xhr文件,點(diǎn)開(kāi)preview我們驚喜的發(fā)現(xiàn),這個(gè)里面有每一張圖id的信息!
![](/d/20211017/b7ab5905b9381e9db7b3194912ab4ba2.gif)
搜尋一圈發(fā)現(xiàn)字典里有效的只有id這個(gè)值,那么id對(duì)于我們的圖片爬取有什么意義呢?通常情況下網(wǎng)址+id就可以定位到具體的圖片,于是我點(diǎn)進(jìn)去一張壁紙,驚喜的發(fā)現(xiàn)跟我想的一樣!
![](/d/20211017/6618140eda395658165c1d4e8a29e983.gif)
最后又到了我們老生常談的頁(yè)數(shù)環(huán)節(jié),在看到這個(gè)api的request url之后大家有沒(méi)有觀察到它其中帶著page_num=2page_size=100這兩個(gè)看著很像頁(yè)碼的參數(shù)呢?我們?cè)偻戮涂吹搅藚?shù)中也正好有這兩個(gè)值!也就是說(shuō)我們只需要更改page_num=2就可以實(shí)現(xiàn)翻頁(yè)了!
![](/d/20211017/08a7e6f26bca2f8041ee73dbb2e90dd3.gif)
url='https://api-sucai.gaoding.com/api/csc-api/topics/9080/modules/18928/templets?'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
}
params_list=[]
for i in range(1,4):
parms ={
'page_num': i,
'page_size': 100
}
params_list.append(parms)
解析提取數(shù)據(jù)
for param in params_list:
response = requests.get(url=url,params=param,headers=headers).json()
for i in range(100):
try:
dict =response[i]
id = dict['id']
url_f = 'https://sucai.gaoding.com/material/'+str(id)
url_f_list.append(url_f)
except:
pass
存儲(chǔ)數(shù)據(jù)
for l in url_f_list:
print(l)
h = requests.get(url=l, headers=headers).content
i = 'exercise/' + l.split('/')[-1]
with open(i, 'wb') as fp:
fp.write(h)
完整代碼
import os
import requests
if not os.path.exists('./exercise'):
os.mkdir('./exercise')
url='https://api-sucai.gaoding.com/api/csc-api/topics/9080/modules/18928/templets?'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
}
params_list=[]
url_f_list=[]
for i in range(1,4):
parms ={
'page_num': i,
'page_size': 100
}
params_list.append(parms)
for param in params_list:
response = requests.get(url=url,params=param,headers=headers).json()
for i in range(100):
try:
dict =response[i]
id = dict['id']
url_f = 'https://sucai.gaoding.com/material/'+str(id)
url_f_list.append(url_f)
except:
pass
for l in url_f_list:
print(l)
#h = requests.get(url=l, headers=headers).content
#i = 'exercise/' + l.split('/')[-1]
#with open(i, 'wb') as fp:
# fp.write(h)
三、selenium模擬登錄
我們要爬取的網(wǎng)站總是免不了登錄這一關(guān)鍵環(huán)節(jié),因此模擬登錄也是一大爬蟲(chóng)基礎(chǔ)。
我們要模擬登錄的網(wǎng)站如下
https://www.icourse163.org/course/BIT-268001
![](/d/20211017/c012088cdc69fa0599c4012fe5e4f291.gif)
選取爬蟲(chóng)策略
既然我們是用selenium模擬登陸,首先肯定要明確我們要模擬的具體內(nèi)容,歸納起來(lái)就是
點(diǎn)擊 登錄|注冊(cè)
點(diǎn)擊 其他登陸方式
點(diǎn)擊 手機(jī)號(hào)登錄
輸入賬號(hào)
輸入密碼
點(diǎn)擊 登錄
在明確該干些什么之后我們就打開(kāi)開(kāi)發(fā)者模式觀察一下這個(gè)登錄框吧。
![](/d/20211017/65d3726060fb445dbd4924600b1e033d.gif)
不看不知道,一看嚇一跳,原來(lái)這里有一個(gè)iframe框架,這就意味著如果我們不做任何處理就查找元素的話可能會(huì)什么都查找不到。這就相當(dāng)于在王家找李家的東西一樣,我們首先需要切換到當(dāng)前iframe
driver.switch_to.frame(driver.find_element_by_xpath('//*[@id="j-ursContainer-1"]/iframe'))
經(jīng)過(guò)這一操作之后我們就可以正常按部就班的進(jìn)行模擬登陸了!
完整代碼
from selenium import webdriver
import time
url = 'https://www.icourse163.org/course/BIT-268001'
driver = webdriver.Chrome()
driver.get(url)
driver.maximize_window()
#time.sleep(2)
driver.find_element_by_xpath('//div[@class="unlogin"]/a').click()
driver.find_element_by_class_name('ux-login-set-scan-code_ft_back').click()
driver.find_element_by_xpath('//ul[@class="ux-tabs-underline_hd"]/li[2]').click()
driver.switch_to.frame(driver.find_element_by_xpath('//*[@id="j-ursContainer-1"]/iframe'))
driver.implicitly_wait(2)#給登錄框一些加載的時(shí)間
driver.find_element_by_css_selector('input[type="tel"]').send_keys('15201359153')
driver.find_element_by_css_selector('input[class="j-inputtext dlemail"]').send_keys('Asdasd123')
driver.implicitly_wait(2)#如果不等待的話可能密碼還沒(méi)輸入結(jié)束就點(diǎn)按登錄鍵了
driver.find_element_by_id('submitBtn').click()
到此這篇關(guān)于python基礎(chǔ)之爬蟲(chóng)入門的文章就介紹到這了,更多相關(guān)python入門爬蟲(chóng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- Python爬蟲(chóng)數(shù)據(jù)的分類及json數(shù)據(jù)使用小結(jié)
- python爬蟲(chóng)scrapy圖書(shū)分類實(shí)例講解
- Python爬蟲(chóng)實(shí)現(xiàn)的根據(jù)分類爬取豆瓣電影信息功能示例
- Python異步爬蟲(chóng)實(shí)現(xiàn)原理與知識(shí)總結(jié)
- Python爬蟲(chóng)之線程池的使用
- python爬蟲(chóng)請(qǐng)求庫(kù)httpx和parsel解析庫(kù)的使用測(cè)評(píng)
- Python爬蟲(chóng)之爬取最新更新的小說(shuō)網(wǎng)站
- 用Python爬蟲(chóng)破解滑動(dòng)驗(yàn)證碼的案例解析
- Python爬蟲(chóng)基礎(chǔ)之爬蟲(chóng)的分類知識(shí)總結(jié)