Python簡單post資訊
從自己別的部落格搬過來的,很久之前的文章,正好放在專欄Python基礎知識裡~不知道對別人有沒有用,希望不會辣眼睛哈哈~
最近學了點關於python的網路爬蟲的知識,簡單記錄一下,這裡主要用到了requests庫和BeautifulSoup庫
Beautiful Soup is a Python library for pulling data out of HTML and XML files. It works with your favorite parser to provide idiomatic ways of navigating, searching, and modifying the parse tree. It commonly saves programmers hours or days of work.
以上是兩個庫的介紹,連結是文件資訊
1、示例頁面
這裡我利用 東北大學的圖書館 的登陸頁面來實現我們的爬蟲功能(ps:沒錯,博主是東北大學的學生..所以我有賬號密碼), 沒有賬號密碼也沒有關係,原理都是差不多的 ,之所以找這個頁面,是因為這個頁面沒有驗證碼,能夠簡單一些,而且像學校的這種頁面一般比較簡單,方便操作
2、簡單分析
首先我用的賬戶和密碼登陸進了東北大學圖書館,我使用的是chrome瀏覽器,開啟開發者模式,我們來看看我們提交了哪些資訊。
登陸進去後,按下F12開啟開發者模式,在Network選項卡下面,我們找到這個檔案,他的request方法是post,應該就是我們要找的檔案了,拉到最下面看到Form Data,紅色框出就是我們登陸時提交的資訊了,一共五個部分,畫紅線的地方是賬號和密碼。搞清楚了post的資訊後,我們就可以寫程式碼來自動提交資訊了。
登陸部分搞清楚了,接下就要分析要抓取的資訊了,現在我要抓取我的
- 外借
- 借閱歷史列表
- 預約請求
要抓取這三個資料,如上圖所示,我當前外借1本書,借閱過65本書,預約請求為0,現在的目的是將這些資料抓取出來,我們按下F12來檢視網頁的原始碼,分析我們應該抓取哪一部分。
如上圖所示,一步步找到了資料所在的標籤,我發現數據都在id=history這個標籤下,所以可以先找到這個標籤,然後再找tr標籤,然後就能找到td標籤裡的資料了。
3、實現的功能
- 自動登陸
- 抓取頁面上的一些資訊,並在控制檯輸出
4、程式碼部分
4.1、post資料的部分
首先貼上這部分的程式碼
def getHTMLText(url): try: kv = {'user-agent': 'Mozilla/5.0'} mydata = {'func':'login-session', 'login_source':'bor-info', 'bor_id': '***', 'bor_verification': '***','bor_library':'NEU50'} re = requests.post(url, data=mydata, headers=kv) re.raise_for_status() re.encoding = re.apparent_encoding return re.text except: print("異常") return""
程式碼如上,我們來分析一下
- kv是為了模擬瀏覽器而定義的字典,因為有些網站如果識別出是爬蟲的話,會拒絕訪問,所以這裡可以修改headers的資訊來模擬瀏覽器登陸。
- mydata裡面存的就是要post的資訊,其中賬號和密碼我用 * 代替了。
- requests.post()就是向指定的url 提交資料,關於requests在網上都能搜的到,就不贅述了。
- re.raise_for_status()這個的含義是如果訪問失敗的話,就會丟出異常。
- re.encoding = re.apparent_encoding修改編碼,保證中文能被正確的解析。
- 這裡採用try except的結構,為了程式的健壯性考慮,讓程式在錯誤的時候不至於崩潰。
- 最後返回我們新的頁面的text。
4.2、抓取資料部分
首先貼上程式碼
def fillBookList(booklist, html): soup = BeautifulSoup(html,"html.parser") for tr in soup.find(id='history').descendants: if isinstance(tr, bs4.element.Tag): temp = tr.find_all('td') if len(temp)>0: booklist.append(temp[1].string.strip()) booklist.append(temp[3].string.strip()) booklist.append(temp[5].string.strip()) break
- 引數分別是我們要填充的列表和目標頁面
- 建立一個BeautifulSoup的物件
- 在整個頁面中查詢id=history的標籤,然後遍歷其所有子孫標籤
- 在遍歷的過程中,標籤的子標籤可能是字串型別,我們要過濾掉這些,所以用了isinstance(tr, bs4.element.Tag)
isinstance 的用法:
語法:
isinstance(object, classinfo)
其中,object 是變數,classinfo 是型別(tuple,dict,int,float,list,bool等) 和 class類若引數 object 是 classinfo 類的例項,或者 object 是 classinfo 類的子類的一個例項, 返回 True。 若 object 不是一個給定型別的的物件, 則返回結果總是False。若 classinfo 不是一種資料型別或者由資料型別構成的元組,將引發一個 TypeError 異常。
- 在標籤中尋找所有td標籤,觀察原始碼發現,第一個td標籤列表就是我們要的,所以一旦找到我們要的資訊以後,就停止查詢,並就資訊存在booklist裡面
4.3、列印資訊
貼上程式碼
def printUnivList(booklist): print("{:^10}\t{:^6}\t{:^10}".format("外借","借閱歷史列表","預約請求")) print("{:^10}\t{:^6}\t{:^10}".format(booklist[0],booklist[1],booklist[2])
這部分很簡單就不說了
4.4、主函式
貼上程式碼
def main(): html = getHTMLText("http://202.118.8.7:8991/F/-?func=bor-info") booklist = [] fillBookList(booklist, html) printUnivList(booklist)
5、測試
成功的在控制檯打印出了我們要的資訊!
6、完整的程式碼
import requests from bs4 importBeautifulSoup importbs4 def getHTMLText(url): try: kv = {'user-agent': 'Mozilla/5.0'} mydata = {'func':'login-session', 'login_source':'bor-info', 'bor_id': '***', 'bor_verification': '***','bor_library':'NEU50'} re = requests.post(url, data=mydata, headers=kv) re.raise_for_status() re.encoding = re.apparent_encoding return re.text except: print("異常") return"" def fillBookList(booklist, html): soup = BeautifulSoup(html,"html.parser") for tr in soup.find(id='history').descendants: if isinstance(tr, bs4.element.Tag): temp = tr.find_all('td') if len(temp)>0: booklist.append(temp[1].string.strip()) booklist.append(temp[3].string.strip()) booklist.append(temp[5].string.strip()) break def printUnivList(booklist): print("{:^10}\t{:^6}\t{:^10}".format("外借","借閱歷史列表","預約請求")) print("{:^10}\t{:^6}\t{:^10}".format(booklist[0],booklist[1],booklist[2])) def main(): html = getHTMLText("http://202.118.8.7:8991/F/-?func=bor-info") booklist = [] fillBookList(booklist, html) printUnivList(booklist) main()