前面九篇文章從基礎(chǔ)到編寫都做了詳細(xì)的介紹了,第十篇么講究個(gè)十全十美,那么我們就來詳細(xì)記錄一下一個(gè)爬蟲程序如何一步步編寫出來的,各位看官可要看仔細(xì)了
先來說一下我們學(xué)校的網(wǎng)站:
http://jwxt.sdu.edu.cn:7777/zhxt_bks/zhxt_bks.html
查詢成績(jī)需要登錄,然后顯示各學(xué)科成績(jī),但是只顯示成績(jī)而沒有績(jī)點(diǎn),也就是加權(quán)平均分。
顯然這樣手動(dòng)計(jì)算績(jī)點(diǎn)是一件非常麻煩的事情。所以我們可以用python做一個(gè)爬蟲來解決這個(gè)問題。
1.決戰(zhàn)前夜
先來準(zhǔn)備一下工具:HttpFox插件。
這是一款http協(xié)議分析插件,分析頁面請(qǐng)求和響應(yīng)的時(shí)間、內(nèi)容、以及瀏覽器用到的COOKIE等。
以我為例,安裝在火狐上即可,效果如圖:
可以非常直觀的查看相應(yīng)的信息。
點(diǎn)擊start是開始檢測(cè),點(diǎn)擊stop暫停檢測(cè),點(diǎn)擊clear清除內(nèi)容。
一般在使用之前,點(diǎn)擊stop暫停,然后點(diǎn)擊clear清屏,確??吹降氖窃L問當(dāng)前頁面獲得的數(shù)據(jù)。
2.深入敵后
下面就去山東大學(xué)的成績(jī)查詢網(wǎng)站,看一看在登錄的時(shí)候,到底發(fā)送了那些信息。
先來到登錄頁面,把httpfox打開,clear之后,點(diǎn)擊start開啟檢測(cè):
輸入完了個(gè)人信息,確保httpfox處于開啟狀態(tài),然后點(diǎn)擊確定提交信息,實(shí)現(xiàn)登錄。
這個(gè)時(shí)候可以看到,httpfox檢測(cè)到了三條信息:
這時(shí)點(diǎn)擊stop鍵,確保捕獲到的是訪問該頁面之后反饋的數(shù)據(jù),以便我們做爬蟲的時(shí)候模擬登陸使用。
3.庖丁解牛
乍一看我們拿到了三個(gè)數(shù)據(jù),兩個(gè)是GET的一個(gè)是POST的,但是它們到底是什么,應(yīng)該怎么用,我們還一無所知。
所以,我們需要挨個(gè)查看一下捕獲到的內(nèi)容。
先看POST的信息:
既然是POST的信息,我們就直接看PostData即可。
可以看到一共POST兩個(gè)數(shù)據(jù),stuid和pwd。
并且從Type的Redirect to可以看出,POST完畢之后跳轉(zhuǎn)到了bks_login2.loginmessage頁面。
由此看出,這個(gè)數(shù)據(jù)是點(diǎn)擊確定之后提交的表單數(shù)據(jù)。
點(diǎn)擊cookie標(biāo)簽,看看cookie信息:
沒錯(cuò),收到了一個(gè)ACCOUNT的cookie,并且在session結(jié)束之后自動(dòng)銷毀。
那么提交之后收到了哪些信息呢?
我們來看看后面的兩個(gè)GET數(shù)據(jù)。
先看第一個(gè),我們點(diǎn)擊content標(biāo)簽可以查看收到的內(nèi)容,是不是有一種生吞活剝的快感-。-HTML源碼暴露無疑了:
看來這個(gè)只是顯示頁面的html源碼而已,點(diǎn)擊cookie,查看cookie的相關(guān)信息:
啊哈,原來html頁面的內(nèi)容是發(fā)送了cookie信息之后才接受到的。
再來看看最后一個(gè)接收到的信息:
大致看了一下應(yīng)該只是一個(gè)叫做style.css的css文件,對(duì)我們沒有太大的作用。
4.冷靜應(yīng)戰(zhàn)
既然已經(jīng)知道了我們向服務(wù)器發(fā)送了什么數(shù)據(jù),也知道了我們接收到了什么數(shù)據(jù),基本的流程如下:
首先,我們POST學(xué)號(hào)和密碼--->然后返回cookie的值然后發(fā)送cookie給服務(wù)器--->返回頁面信息。獲取到成績(jī)頁面的數(shù)據(jù),用正則表達(dá)式將成績(jī)和學(xué)分單獨(dú)取出并計(jì)算加權(quán)平均數(shù)。
OK,看上去好像很簡(jiǎn)單的樣紙。那下面我們就來試試看吧。
但是在實(shí)驗(yàn)之前,還有一個(gè)問題沒有解決,就是POST的數(shù)據(jù)到底發(fā)送到了哪里?
再來看一下當(dāng)初的頁面:
很明顯是用一個(gè)html框架來實(shí)現(xiàn)的,也就是說,我們?cè)诘刂窓诳吹降牡刂凡⒉皇怯疫吿峤槐韱蔚牡刂贰?/p>
那么怎樣才能獲得真正的地址-。-右擊查看頁面源代碼:
嗯沒錯(cuò),那個(gè)name="w_right"的就是我們要的登錄頁面。
網(wǎng)站的原來的地址是:
http://jwxt.sdu.edu.cn:7777/zhxt_bks/zhxt_bks.html
所以,真正的表單提交的地址應(yīng)該是:
http://jwxt.sdu.edu.cn:7777/zhxt_bks/xk_login.html
輸入一看,果不其然:
靠居然是清華大學(xué)的選課系統(tǒng)。。。目測(cè)是我校懶得做頁面了就直接借了。。結(jié)果連標(biāo)題都不改一下。。。
但是這個(gè)頁面依舊不是我們需要的頁面,因?yàn)槲覀兊腜OST數(shù)據(jù)提交到的頁面,應(yīng)該是表單form的ACTION中提交到的頁面。
也就是說,我們需要查看源碼,來知道POST數(shù)據(jù)到底發(fā)送到了哪里:
嗯,目測(cè)這個(gè)才是提交POST數(shù)據(jù)的地址。
整理到地址欄中,完整的地址應(yīng)該如下:
http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bks_login2.login
(獲取的方式很簡(jiǎn)單,在火狐瀏覽器中直接點(diǎn)擊那個(gè)鏈接就能看到這個(gè)鏈接的地址了)
5.小試牛刀
接下來的任務(wù)就是:用python模擬發(fā)送一個(gè)POST的數(shù)據(jù)并取到返回的cookie值。
關(guān)于cookie的操作可以看看這篇博文:
http://www.jb51.net/article/57144.htm
我們先準(zhǔn)備一個(gè)POST的數(shù)據(jù),再準(zhǔn)備一個(gè)cookie的接收,然后寫出源碼如下:
# -*- coding: utf-8 -*- #--------------------------------------- # 程序:山東大學(xué)爬蟲 # 版本:0.1 # 作者:why # 日期:2013-07-12 # 語言:Python 2.7 # 操作:輸入學(xué)號(hào)和密碼 # 功能:輸出成績(jī)的加權(quán)平均值也就是績(jī)點(diǎn) #--------------------------------------- import urllib import urllib2 import cookielib cookie = cookielib.CookieJar() opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie)) #需要POST的數(shù)據(jù)# postdata=urllib.urlencode({ 'stuid':'201100300428', 'pwd':'921030' }) #自定義一個(gè)請(qǐng)求# req = urllib2.Request( url = 'http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bks_login2.login', data = postdata ) #訪問該鏈接# result = opener.open(req) #打印返回的內(nèi)容# print result.read()
如此這般之后,再看看運(yùn)行的效果:
ok,如此這般,我們就算模擬登陸成功了。
6.偷天換日
接下來的任務(wù)就是用爬蟲獲取到學(xué)生的成績(jī)。
再來看看源網(wǎng)站。
開啟HTTPFOX之后,點(diǎn)擊查看成績(jī),發(fā)現(xiàn)捕獲到了如下的數(shù)據(jù):
點(diǎn)擊第一個(gè)GET的數(shù)據(jù),查看內(nèi)容可以發(fā)現(xiàn)Content就是獲取到的成績(jī)的內(nèi)容。
而獲取到的頁面鏈接,從頁面源代碼中右擊查看元素,可以看到點(diǎn)擊鏈接之后跳轉(zhuǎn)的頁面(火狐瀏覽器只需要右擊,“查看此框架”,即可):
從而可以得到查看成績(jī)的鏈接如下:
http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bkscjcx.curscopre
7.萬事俱備
現(xiàn)在萬事俱備啦,所以只需要把鏈接應(yīng)用到爬蟲里面,看看能否查看到成績(jī)的頁面。
從httpfox可以看到,我們發(fā)送了一個(gè)cookie才能返回成績(jī)的信息,所以我們就用python模擬一個(gè)cookie的發(fā)送,以此來請(qǐng)求成績(jī)的信息:
# -*- coding: utf-8 -*- #--------------------------------------- # 程序:山東大學(xué)爬蟲 # 版本:0.1 # 作者:why # 日期:2013-07-12 # 語言:Python 2.7 # 操作:輸入學(xué)號(hào)和密碼 # 功能:輸出成績(jī)的加權(quán)平均值也就是績(jī)點(diǎn) #--------------------------------------- import urllib import urllib2 import cookielib #初始化一個(gè)CookieJar來處理Cookie的信息# cookie = cookielib.CookieJar() #創(chuàng)建一個(gè)新的opener來使用我們的CookieJar# opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie)) #需要POST的數(shù)據(jù)# postdata=urllib.urlencode({ 'stuid':'201100300428', 'pwd':'921030' }) #自定義一個(gè)請(qǐng)求# req = urllib2.Request( url = 'http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bks_login2.login', data = postdata ) #訪問該鏈接# result = opener.open(req) #打印返回的內(nèi)容# print result.read() #打印cookie的值 for item in cookie: print 'Cookie:Name = '+item.name print 'Cookie:Value = '+item.value #訪問該鏈接# result = opener.open('http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bkscjcx.curscopre') #打印返回的內(nèi)容# print result.read()
按下F5運(yùn)行即可,看看捕獲到的數(shù)據(jù)吧:
既然這樣就沒有什么問題了吧,用正則表達(dá)式將數(shù)據(jù)稍稍處理一下,取出學(xué)分和相應(yīng)的分?jǐn)?shù)就可以了。
8.手到擒來
這么一大堆html源碼顯然是不利于我們處理的,下面要用正則表達(dá)式來摳出必須的數(shù)據(jù)。
關(guān)于正則表達(dá)式的教程可以看看這個(gè)博文:
http://www.jb51.net/article/57150.htm
我們來看看成績(jī)的源碼:
既然如此,用正則表達(dá)式就易如反掌了。
我們將代碼稍稍整理一下,然后用正則來取出數(shù)據(jù):
# -*- coding: utf-8 -*- #--------------------------------------- # 程序:山東大學(xué)爬蟲 # 版本:0.1 # 作者:why # 日期:2013-07-12 # 語言:Python 2.7 # 操作:輸入學(xué)號(hào)和密碼 # 功能:輸出成績(jī)的加權(quán)平均值也就是績(jī)點(diǎn) #--------------------------------------- import urllib import urllib2 import cookielib import re class SDU_Spider: # 申明相關(guān)的屬性 def __init__(self): self.loginUrl = 'http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bks_login2.login' # 登錄的url self.resultUrl = 'http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bkscjcx.curscopre' # 顯示成績(jī)的url self.cookieJar = cookielib.CookieJar() # 初始化一個(gè)CookieJar來處理Cookie的信息 self.postdata=urllib.urlencode({'stuid':'201100300428','pwd':'921030'}) # POST的數(shù)據(jù) self.weights = [] #存儲(chǔ)權(quán)重,也就是學(xué)分 self.points = [] #存儲(chǔ)分?jǐn)?shù),也就是成績(jī) self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookieJar)) def sdu_init(self): # 初始化鏈接并且獲取cookie myRequest = urllib2.Request(url = self.loginUrl,data = self.postdata) # 自定義一個(gè)請(qǐng)求 result = self.opener.open(myRequest) # 訪問登錄頁面,獲取到必須的cookie的值 result = self.opener.open(self.resultUrl) # 訪問成績(jī)頁面,獲得成績(jī)的數(shù)據(jù) # 打印返回的內(nèi)容 # print result.read() self.deal_data(result.read().decode('gbk')) self.print_data(self.weights); self.print_data(self.points); # 將內(nèi)容從頁面代碼中摳出來 def deal_data(self,myPage): myItems = re.findall('<TR>.*?<p.*?<p.*?<p.*?<p.*?<p.*?>(.*?)</p>.*?<p.*?<p.*?>(.*?)</p>.*?</TR>',myPage,re.S) #獲取到學(xué)分 for item in myItems: self.weights.append(item[0].encode('gbk')) self.points.append(item[1].encode('gbk')) # 將內(nèi)容從頁面代碼中摳出來 def print_data(self,items): for item in items: print item #調(diào)用 mySpider = SDU_Spider() mySpider.sdu_init()
水平有限,,正則是有點(diǎn)丑,。運(yùn)行的效果如圖:
ok,接下來的只是數(shù)據(jù)的處理問題了。。
9.凱旋而歸
完整的代碼如下,至此一個(gè)完整的爬蟲項(xiàng)目便完工了。
# -*- coding: utf-8 -*- #--------------------------------------- # 程序:山東大學(xué)爬蟲 # 版本:0.1 # 作者:why # 日期:2013-07-12 # 語言:Python 2.7 # 操作:輸入學(xué)號(hào)和密碼 # 功能:輸出成績(jī)的加權(quán)平均值也就是績(jī)點(diǎn) #--------------------------------------- import urllib import urllib2 import cookielib import re import string class SDU_Spider: # 申明相關(guān)的屬性 def __init__(self): self.loginUrl = 'http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bks_login2.login' # 登錄的url self.resultUrl = 'http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bkscjcx.curscopre' # 顯示成績(jī)的url self.cookieJar = cookielib.CookieJar() # 初始化一個(gè)CookieJar來處理Cookie的信息 self.postdata=urllib.urlencode({'stuid':'201100300428','pwd':'921030'}) # POST的數(shù)據(jù) self.weights = [] #存儲(chǔ)權(quán)重,也就是學(xué)分 self.points = [] #存儲(chǔ)分?jǐn)?shù),也就是成績(jī) self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookieJar)) def sdu_init(self): # 初始化鏈接并且獲取cookie myRequest = urllib2.Request(url = self.loginUrl,data = self.postdata) # 自定義一個(gè)請(qǐng)求 result = self.opener.open(myRequest) # 訪問登錄頁面,獲取到必須的cookie的值 result = self.opener.open(self.resultUrl) # 訪問成績(jī)頁面,獲得成績(jī)的數(shù)據(jù) # 打印返回的內(nèi)容 # print result.read() self.deal_data(result.read().decode('gbk')) self.calculate_date(); # 將內(nèi)容從頁面代碼中摳出來 def deal_data(self,myPage): myItems = re.findall('<TR>.*?<p.*?<p.*?<p.*?<p.*?<p.*?>(.*?)</p>.*?<p.*?<p.*?>(.*?)</p>.*?</TR>',myPage,re.S) #獲取到學(xué)分 for item in myItems: self.weights.append(item[0].encode('gbk')) self.points.append(item[1].encode('gbk')) #計(jì)算績(jī)點(diǎn),如果成績(jī)還沒出來,或者成績(jī)是優(yōu)秀良好,就不運(yùn)算該成績(jī) def calculate_date(self): point = 0.0 weight = 0.0 for i in range(len(self.points)): if(self.points[i].isdigit()): point += string.atof(self.points[i])*string.atof(self.weights[i]) weight += string.atof(self.weights[i]) print point/weight #調(diào)用 mySpider = SDU_Spider() mySpider.sdu_init()
相關(guān)推薦:
python動(dòng)態(tài)爬蟲的實(shí)例分享
以上是零基礎(chǔ)寫python爬蟲之爬蟲編寫全記錄_python的詳細(xì)內(nèi)容。更多信息請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

熱AI工具

Undress AI Tool
免費(fèi)脫衣服圖片

Undresser.AI Undress
人工智能驅(qū)動(dòng)的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover
用于從照片中去除衣服的在線人工智能工具。

Clothoff.io
AI脫衣機(jī)

Video Face Swap
使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費(fèi)的代碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
功能強(qiáng)大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6
視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版
神級(jí)代碼編輯軟件(SublimeText3)

用戶語音輸入通過前端JavaScript的MediaRecorderAPI捕獲并發(fā)送至PHP后端;2.PHP將音頻保存為臨時(shí)文件后調(diào)用STTAPI(如Google或百度語音識(shí)別)轉(zhuǎn)換為文本;3.PHP將文本發(fā)送至AI服務(wù)(如OpenAIGPT)獲取智能回復(fù);4.PHP再調(diào)用TTSAPI(如百度或Google語音合成)將回復(fù)轉(zhuǎn)為語音文件;5.PHP將語音文件流式返回前端播放,完成交互。整個(gè)流程由PHP主導(dǎo)數(shù)據(jù)流轉(zhuǎn)與錯(cuò)誤處理,確保各環(huán)節(jié)無縫銜接。

要實(shí)現(xiàn)PHP結(jié)合AI進(jìn)行文本糾錯(cuò)與語法優(yōu)化,需按以下步驟操作:1.選擇適合的AI模型或API,如百度、騰訊API或開源NLP庫(kù);2.通過PHP的curl或Guzzle調(diào)用API并處理返回結(jié)果;3.在應(yīng)用中展示糾錯(cuò)信息并允許用戶選擇是否采納;4.使用php-l和PHP_CodeSniffer進(jìn)行語法檢測(cè)與代碼優(yōu)化;5.持續(xù)收集反饋并更新模型或規(guī)則以提升效果。選擇AIAPI時(shí)應(yīng)重點(diǎn)評(píng)估準(zhǔn)確率、響應(yīng)速度、價(jià)格及對(duì)PHP的支持。代碼優(yōu)化應(yīng)遵循PSR規(guī)范、合理使用緩存、避免循環(huán)查詢、定期審查代碼,并借助X

選擇合適的PHP框架需根據(jù)項(xiàng)目需求綜合考慮:Laravel適合快速開發(fā),提供EloquentORM和Blade模板引擎,便于數(shù)據(jù)庫(kù)操作和動(dòng)態(tài)表單渲染;Symfony更靈活,適合復(fù)雜系統(tǒng);CodeIgniter輕量,適用于對(duì)性能要求較高的簡(jiǎn)單應(yīng)用。2.確保AI模型準(zhǔn)確性需從高質(zhì)量數(shù)據(jù)訓(xùn)練、合理選擇評(píng)估指標(biāo)(如準(zhǔn)確率、召回率、F1值)、定期性能評(píng)估與模型調(diào)優(yōu)入手,并通過單元測(cè)試和集成測(cè)試保障代碼質(zhì)量,同時(shí)持續(xù)監(jiān)控輸入數(shù)據(jù)以防止數(shù)據(jù)漂移。3.保護(hù)用戶隱私需采取多項(xiàng)措施:對(duì)敏感數(shù)據(jù)進(jìn)行加密存儲(chǔ)(如AES

使用Seaborn的jointplot可快速可視化兩個(gè)變量間的關(guān)系及各自分布;2.基礎(chǔ)散點(diǎn)圖通過sns.jointplot(data=tips,x="total_bill",y="tip",kind="scatter")實(shí)現(xiàn),中心為散點(diǎn)圖,上下和右側(cè)顯示直方圖;3.添加回歸線和密度信息可用kind="reg",并結(jié)合marginal_kws設(shè)置邊緣圖樣式;4.數(shù)據(jù)量大時(shí)推薦kind="hex",用

PHP結(jié)合AI做視頻內(nèi)容分析的核心思路是讓PHP作為后端“膠水”,先上傳視頻到云存儲(chǔ),再調(diào)用AI服務(wù)(如GoogleCloudVideoAI等)進(jìn)行異步分析;2.PHP解析返回的JSON結(jié)果,提取人物、物體、場(chǎng)景、語音等信息生成智能標(biāo)簽并存入數(shù)據(jù)庫(kù);3.優(yōu)勢(shì)在于利用PHP成熟的Web生態(tài)快速集成AI能力,適合已有PHP系統(tǒng)的項(xiàng)目高效落地;4.常見挑戰(zhàn)包括大文件處理(用預(yù)簽名URL直傳云存儲(chǔ))、異步任務(wù)(引入消息隊(duì)列)、成本控制(按需分析 預(yù)算監(jiān)控)和結(jié)果優(yōu)化(標(biāo)簽規(guī)范化);5.智能標(biāo)簽顯著提升視

PHP開發(fā)AI文本摘要的核心是作為協(xié)調(diào)器調(diào)用外部AI服務(wù)API(如OpenAI、HuggingFace),實(shí)現(xiàn)文本預(yù)處理、API請(qǐng)求、響應(yīng)解析與結(jié)果展示;2.局限性在于計(jì)算性能弱、AI生態(tài)薄弱,應(yīng)對(duì)策略為借力API、服務(wù)解耦和異步處理;3.模型選擇需權(quán)衡摘要質(zhì)量、成本、延遲、并發(fā)、數(shù)據(jù)隱私,推薦使用GPT或BART/T5等抽象式模型;4.性能優(yōu)化包括緩存、異步隊(duì)列、批量處理和就近區(qū)域選擇,錯(cuò)誤處理需覆蓋限流重試、網(wǎng)絡(luò)超時(shí)、密鑰安全、輸入驗(yàn)證及日志記錄,以確保系統(tǒng)穩(wěn)定高效運(yùn)行。

要將AI情感計(jì)算技術(shù)融入PHP應(yīng)用,核心是利用云服務(wù)AIAPI(如Google、AWS、Azure)進(jìn)行情感分析,通過HTTP請(qǐng)求發(fā)送文本并解析返回的JSON結(jié)果,將情感數(shù)據(jù)存入數(shù)據(jù)庫(kù),從而實(shí)現(xiàn)用戶反饋的自動(dòng)化處理與數(shù)據(jù)洞察。具體步驟包括:1.選擇適合的AI情感分析API,綜合考慮準(zhǔn)確性、成本、語言支持和集成復(fù)雜度;2.使用Guzzle或curl發(fā)送請(qǐng)求,存儲(chǔ)情感分?jǐn)?shù)、標(biāo)簽及強(qiáng)度等信息;3.構(gòu)建可視化儀表盤,支持優(yōu)先級(jí)排序、趨勢(shì)分析、產(chǎn)品迭代方向和用戶細(xì)分;4.應(yīng)對(duì)技術(shù)挑戰(zhàn),如API調(diào)用限制、數(shù)

字符串列表可用join()方法合并,如''.join(words)得到"HelloworldfromPython";2.數(shù)字列表需先用map(str,numbers)或[str(x)forxinnumbers]轉(zhuǎn)為字符串后才能join;3.任意類型列表可直接用str()轉(zhuǎn)換為帶括號(hào)和引號(hào)的字符串,適用于調(diào)試;4.自定義格式可用生成器表達(dá)式結(jié)合join()實(shí)現(xiàn),如'|'.join(f"[{item}]"foriteminitems)輸出"[a]|[
