利用python requests庫模擬登陸知乎
阿新 • • 發佈:2019-02-18
當初搜模擬登陸的時候在知乎上也找到一些內容。
以下是程式碼
來自知乎:import requests import time import json import os import re import sys import subprocess from bs4 import BeautifulSoup as BS class ZhiHuClient(object): """連線知乎的工具類,維護一個Session 2015.11.11 用法: client = ZhiHuClient() # 第一次使用時需要呼叫此方法登入一次,生成cookie檔案 # 以後可以跳過這一步 client.login("username", "password") # 用這個session進行其他網路操作,詳見requests庫 session = client.getSession() """ # 網址引數是賬號型別 TYPE_PHONE_NUM = "phone_num" TYPE_EMAIL = "email" loginURL = r"http://www.zhihu.com/login/{0}" homeURL = r"http://www.zhihu.com" captchaURL = r"http://www.zhihu.com/captcha.gif" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Encoding": "gzip, deflate", "Host": "www.zhihu.com", "Upgrade-Insecure-Requests": "1", } captchaFile = os.path.join(sys.path[0], "captcha.gif") cookieFile = os.path.join(sys.path[0], "cookie") def __init__(self): os.chdir(sys.path[0]) # 設定指令碼所在目錄為當前工作目錄 self.__session = requests.Session() self.__session.headers = self.headers # 用self呼叫類變數是防止將來類改名 # 若已經有 cookie 則直接登入 self.__cookie = self.__loadCookie() if self.__cookie: print("檢測到cookie檔案,直接使用cookie登入") self.__session.cookies.update(self.__cookie) soup = BS(self.open(r"http://www.zhihu.com/").text, "html.parser") print("已登陸賬號: %s" % soup.find("span", class_="name").getText()) else: print("沒有找到cookie檔案,請呼叫login方法登入一次!") # 登入 def login(self, username, password): """ 驗證碼錯誤返回: {'errcode': 1991829, 'r': 1, 'data': {'captcha': '請提交正確的驗證碼 :('}, 'msg': '請提交正確的驗證碼 :('} 登入成功返回: {'r': 0, 'msg': '登陸成功'} """ self.__username = username self.__password = password self.__loginURL = self.loginURL.format(self.__getUsernameType()) # 隨便開個網頁,獲取登陸所需的_xsrf html = self.open(self.homeURL).text soup = BS(html, "html.parser") _xsrf = soup.find("input", {"name": "_xsrf"})["value"] # 下載驗證碼圖片 while True: captcha = self.open(self.captchaURL).content with open(self.captchaFile, "wb") as output: output.write(captcha) # 人眼識別 print("=" * 50) print("已開啟驗證碼圖片,請識別!") subprocess.call(self.captchaFile, shell=True) captcha = input("請輸入驗證碼:") os.remove(self.captchaFile) # 傳送POST請求 data = { "_xsrf": _xsrf, "password": self.__password, "remember_me": "true", self.__getUsernameType(): self.__username, "captcha": captcha } res = self.__session.post(self.__loginURL, data=data) print("=" * 50) # print(res.text) # 輸出指令碼資訊,除錯用 if res.json()["r"] == 0: print("登入成功") self.__saveCookie() break else: print("登入失敗") print("錯誤資訊 --->", res.json()["msg"]) def __getUsernameType(self): """判斷使用者名稱型別 經測試,網頁的判斷規則是純數字為phone_num,其他為email """ if self.__username.isdigit(): return self.TYPE_PHONE_NUM return self.TYPE_EMAIL def __saveCookie(self): """cookies 序列化到檔案 即把dict物件轉化成字串儲存 """ with open(self.cookieFile, "w") as output: cookies = self.__session.cookies.get_dict() json.dump(cookies, output) print("=" * 50) print("已在同目錄下生成cookie檔案:", self.cookieFile) def __loadCookie(self): """讀取cookie檔案,返回反序列化後的dict物件,沒有則返回None""" if os.path.exists(self.cookieFile): print("=" * 50) with open(self.cookieFile, "r") as f: cookie = json.load(f) return cookie return None def open(self, url, delay=0, timeout=10): """開啟網頁,返回Response物件""" if delay: time.sleep(delay) return self.__session.get(url, timeout=timeout) def getSession(self): return self.__session if __name__ == '__main__': client = ZhiHuClient() client.login('xxxxxx','xxxxxxxx') # 第一次使用時需要呼叫此方法登入一次,生成cookie檔案 # 以後可以跳過這一步 # client.login("username", "password") # 用這個session進行其他網路操作,詳見requests庫 session = client.getSession() r=session.get('http://www.zhihu.com') print(s.text)
這模擬登陸的程式碼可以作為參考。
最後是關於獲取天氣預報的爬蟲程式碼:
思路很簡單。但主要也是正則表示式的書寫,還是得勤加練習才對。import urllib.request import re def GetHtmlCode(url): page = urllib.request.urlopen(url) htmlCode = page.read().decode('gbk') page.close() return htmlCode def FindGXUrl(homePage): gx_re_vague=r'<a href="[\S]+" rel="[\S]+">江蘇</a>' gx_url_vague=re.search(gx_re_vague,homePage).group() gx_re=r'http://[\w\./]+\.htm' gx_url=re.search(gx_re,gx_url_vague).group() return gx_url def FindNNUrl(GXPage): by_re_vague=r'<a href="[\S]+?" title="[\S]+?">南京</a>' nn_url_vague=re.search(by_re_vague,GXPage).group() by_re=r'/[\S]+?\.htm' nn_url_suffix=re.search(by_re,nn_url_vague).group() return nn_url_suffix def GetWeatherBlockList(WeatherPage): weatherBlock_re=r'<li class="week-detail-now" >[\s\S]+?</li>' weather_re=re.compile(weatherBlock_re) weatherList=re.findall(weather_re,WeatherPage) return weatherList class Weather: date='' daytime='' nighttime='' temperatureL='' temperatureH='' def __init__(self,d,dT,nT,tL,tH): self.date=d self.daytime=dT self.nighttime=nT self.temperatureL=tL self.temperatureH=tH def print(self): print('\n%s:白天:%s,夜間:%s,\n最低溫度:%sC,最高溫度:%sC\n'%(self.date,self.daytime,self.nighttime,self.temperatureL,self.temperatureH)) def MakeWeatherInfo(block): dA_re=r'[\d]{2}月[\d]{2}日' dA=re.search(dA_re,block).group() dT_re=r'<b><font class="gray">白天:</font>.{1,6}</b>' dT=re.search(dT_re,block).group() dT=re.sub(r'<b>.+</font>','',dT) dT=re.sub(r'</b>','',dT) nT_re=r'<b><font class="gray">夜間:</font>.{1,6}</b>' nT=re.search(nT_re,block).group() nT=re.sub(r'<b>.+</font>','',nT) nT=re.sub(r'</b>','',nT) t_re=r'<font class="blue">.{0,4}</font>~<font class="red">.{0,4}</font>' t=re.search(t_re,block).group() t=re.findall(r'[\d]+',t) return Weather(dA,dT,nT,t[0],t[1]) homePage=GetHtmlCode("http://tianqi.2345.com/") gx_url=FindGXUrl(homePage) GXPage=GetHtmlCode(gx_url) nn_url_suffix=FindNNUrl(GXPage) nn_url='http://tianqi.2345.com'+nn_url_suffix NNPage=GetHtmlCode(nn_url) weatherList=GetWeatherBlockList(NNPage)#get a list of two days' weather weather1=MakeWeatherInfo(weatherList[0]) weather2=MakeWeatherInfo(weatherList[1]) weather1.print() weather2.print()
用Python實現爬蟲的確非常簡單。但是利用scrapy框架之類的剛接觸一會發現利用Python3連安裝都是各種error.累覺不愛。
現在都是單執行緒。以後能做多執行緒和分散式爬蟲的時候再回來補充吧。
之後幾個月打算研究django,但是這估計也是個很大的坑呢233333.還得學習SQL語言balabala..挑戰性很足。
如果學到什麼東西在往部落格裡放吧。記錄一下學習的過程。
大學實在是太枯燥了。也許是我不太喜歡社交呢233333。