Python製作一款爬蟲軟體,爬取公眾號文章,爬蟲之路,永無止境
今天拿手機看公眾號裡面的文章,不小心退出來,進去之後還得一頁一頁地翻,好麻煩,突發奇想,把資訊爬下來,想看哪個看哪個。。嘿嘿,來自程式設計師的快樂。
爬蟲操作演示
電腦卡,各位別見怪。。。
很多人學習python,不知道從何學起。 很多人學習python,掌握了基本語法過後,不知道在哪裡尋找案例上手。 很多已經做案例的人,卻不知道如何去學習更加高深的知識。 那麼針對這三類人,我給大家提供一個好的學習平臺,免費領取視訊教程,電子書籍,以及課程的原始碼! QQ群:861355058 歡迎加入,一起討論 一起學習!
開發工具
python
pycharm
selenium
tkinter
xlwt
開發思路
首先
start_url="https://mp.weixin.qq.com/"
掃碼註冊一下微信公眾平臺,有的話直接忽略,掃碼登入即可。(註冊個人訂閱號就行)
利用selenium自動操作掃碼登入獲得cookie值,之後響應要用cookie
要先下載webdriver外掛
外掛你下載對應谷歌瀏覽器的版本,下載之後會獲得chromedriver.exe,然後把這個chromedriver.exe放在python直譯器的python.exe檔案的同級目錄下就可以了
登入進去介面為:
響應拿回網頁原始碼,拿回token值,token值是有時效性的
操作點開要搜尋公眾號的位置
搜尋想要爬取的公眾號名字
右擊開啟檢查,拿回fakeid值,確定公眾號,具有唯一性
本文以CSDN為例,爬取公眾號的文章
翻頁
開啟headers,拿回第一頁的requests url
https://mp.weixin.qq.com/cgi-bin/appmsg?action=list_ex&begin=0&count=5&fakeid=MjM5MjAwODM4MA==&type=9&query=&token=1008822872&lang=zh_CN&f=json&ajax=1
拿回第二頁的地址
https://mp.weixin.qq.com/cgi-bin/appmsg?action=list_ex&begin=5&count=5&fakeid=MjM5MjAwODM4MA==&type=9&query=&token=1008822872&lang=zh_CN&f=json&ajax=1
對比可以發現begin引數以5的速度增長
直接原始碼展示
# !/usr/bin/nev python # -*-coding:utf8-*- import tkinter as tk from selenium import webdriver import time, re, jsonpath, xlwt from requests_html import HTMLSession session = HTMLSession() class GZHSpider(object): def __init__(self): """定義視覺化視窗,並設定視窗和主題大小布局""" self.window = tk.Tk() self.window.title('公眾號資訊採集') self.window.geometry('800x600') """建立label_user按鈕,與說明書""" self.label_user = tk.Label(self.window, text='需要爬取的公眾號:', font=('Arial', 12), width=30, height=2) self.label_user.pack() """建立label_user關聯輸入""" self.entry_user = tk.Entry(self.window, show=None, font=('Arial', 14)) self.entry_user.pack(after=self.label_user) """建立label_passwd按鈕,與說明書""" self.label_passwd = tk.Label(self.window, text="爬取多少頁:(小於100)", font=('Arial', 12), width=30, height=2) self.label_passwd.pack() """建立label_passwd關聯輸入""" self.entry_passwd = tk.Entry(self.window, show=None, font=('Arial', 14)) self.entry_passwd.pack(after=self.label_passwd) """建立Text富文字框,用於按鈕操作結果的展示""" self.text1 = tk.Text(self.window, font=('Arial', 12), width=85, height=22) self.text1.pack() """定義按鈕1,繫結觸發事件方法""" self.button_1 = tk.Button(self.window, text='爬取', font=('Arial', 12), width=10, height=1, command=self.parse_hit_click_1) self.button_1.pack(before=self.text1) """定義按鈕2,繫結觸發事件方法""" self.button_2 = tk.Button(self.window, text='清除', font=('Arial', 12), width=10, height=1, command=self.parse_hit_click_2) self.button_2.pack(anchor="e") def parse_hit_click_1(self): """定義觸發事件1,呼叫main函式""" user_name = self.entry_user.get() pass_wd = int(self.entry_passwd.get()) self.main(user_name, pass_wd) def main(self, user_name, pass_wd): # 網頁登入 driver_path = r'D:\python\chromedriver.exe' driver = webdriver.Chrome(executable_path=driver_path) driver.get('https://mp.weixin.qq.com/') time.sleep(2) # 網頁最大化 driver.maximize_window() # 拿微信掃描登入 time.sleep(20) # 獲得登入的cookies cookies_list = driver.get_cookies() # 轉化成能用的cookie格式 cookie = [item["name"] + "=" + item["value"] for item in cookies_list] cookie_str = '; '.join(item for item in cookie) # 請求頭 headers_1 = { 'cookie': cookie_str, 'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ' 'Chrome/91.0.4472.77 Safari/537.36' } # 起始地址 start_url = 'https://mp.weixin.qq.com/' response = session.get(start_url, headers=headers_1).content.decode() # 拿到token值,token值是有時效性的 token = re.findall(r'token=(\d+)', response)[0] # 搜尋出所有跟輸入的公眾號有關的 next_url = f'https://mp.weixin.qq.com/cgi-bin/searchbiz?action=search_biz&begin=0&count=5&query={user_name}&token=' \ f'{token}&lang=zh_CN&f=json&ajax=1' # 獲取響應 response_1 = session.get(next_url, headers=headers_1).content.decode() # 拿到fakeid的值,確定公眾號,唯一的 fakeid = re.findall(r'"fakeid":"(.*?)",', response_1)[0] # 構造公眾號的url地址 next_url_2 = 'https://mp.weixin.qq.com/cgi-bin/appmsg?' data = { 'action': 'list_ex', 'begin': '0', 'count': '5', 'fakeid': fakeid, 'type': '9', 'query': '', 'token': token, 'lang': 'zh_CN', 'f': 'json', 'ajax': '1' } headers_2 = { 'cookie': cookie_str, 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ' 'Chrome/91.0.4472.77 Safari/537.36', 'referer': f'https://mp.weixin.qq.com/cgi-bin/appmsgtemplate?action=edit&lang=zh_CN&token={token}', 'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"', 'sec-ch-ua-mobile': '?0', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'x-requested-with': 'XMLHttpRequest' } # 表的建立 workbook = xlwt.Workbook(encoding='gbk', style_compression=0) sheet = workbook.add_sheet('test', cell_overwrite_ok=True) j = 1 # 構造表頭 sheet.write(0, 0, '時間') sheet.write(0, 1, '標題') sheet.write(0, 2, '地址') # 迴圈翻頁 for i in range(pass_wd): data["begin"] = i * 5 time.sleep(3) # 獲取響應的json資料 response_2 = session.get(next_url_2, params=data, headers=headers_2).json() # jsonpath 獲取時間,標題,地址 title_list = jsonpath.jsonpath(response_2, '$..title') url_list = jsonpath.jsonpath(response_2, '$..link') create_time_list = jsonpath.jsonpath(response_2, '$..create_time') # 將時間戳轉化為北京時間 list_1 = [] for create_time in create_time_list: time_local = time.localtime(int(create_time)) time_1 = time.strftime("%Y-%m-%d", time_local) time_2 = time.strftime("%H:%M:%S", time_local) time_3 = time_1 + ' ' + time_2 list_1.append(time_3) # for迴圈遍歷 for times, title, url in zip(list_1, title_list, url_list): # 其中的'0-行, 0-列'指定表中的單元 sheet.write(j, 0, times) sheet.write(j, 1, title) sheet.write(j, 2, url) j = j + 1 # 視窗顯示程序 self.text1.insert("insert", f'*****************第{i+1}頁爬取成功*****************') time.sleep(2) self.text1.insert("insert", '\n ') self.text1.insert("insert", '\n ') # 最後儲存成功 workbook.save(f'{user_name}公眾號資訊.xls') print(f"*********{user_name}公眾號資訊儲存成功*********") def parse_hit_click_2(self): """定義觸發事件2,刪除文字框中內容""" self.entry_user.delete(0, "end") self.entry_passwd.delete(0, "end") self.text1.delete("1.0", "end") def center(self): """建立視窗居中函式方法""" ws = self.window.winfo_screenwidth() hs = self.window.winfo_screenheight() x = int((ws / 2) - (800 / 2)) y = int((hs / 2) - (600 / 2)) self.window.geometry('{}x{}+{}+{}'.format(800, 600, x, y)) def run_loop(self): """禁止修改窗體大小規格""" self.window.resizable(False, False) """視窗居中""" self.center() """視窗維持--持久化""" self.window.mainloop() if __name__ == '__main__': g = GZHSpider() g.run_loop()
程式碼寫完打包一下,就可以發給客戶了