【GUI開發案例】用python爬百度搜索結果,並開發成exe桌面軟體!

来源:https://www.cnblogs.com/mashukui/archive/2022/11/24/16921221.html
-Advertisement-
Play Games

用python爬蟲技術,爬取百度搜索結果數據,包含欄位: 頁碼、標題、百度鏈接、真實鏈接、簡介、網站名稱。 並把源碼封裝成exe文件,方便沒有python環境,或者不懂技術的人使用它。 ...


一、背景介紹

你好,我是 @馬哥python說 ,一名10年程式猿。

1.1 老版本

之前我開發過一個百度搜索的python爬蟲代碼,具體如下:
【python爬蟲案例】用python爬取百度的搜索結果!
這個爬蟲代碼自發佈以來,受到了眾多小伙伴的關註:

但是,很多不懂python編程的小伙伴無法使用它,非常痛苦!

於是,我把這個程式封裝成了一個桌面軟體(exe文件),無需python運行環境也可以使用。

1.2 爬取目標

1.3 軟體運行截圖

1.4 爬取數據

1.5 實現思路

通過python爬蟲技術,爬取百度搜索結果數據,包含欄位:

頁碼、標題、百度鏈接、真實鏈接、簡介、網站名稱。

並把源碼封裝成exe文件,方便沒有python環境,或者不懂技術的人使用它。

二、代碼講解

2.1 爬蟲

首先,導入需要用到的庫:

import requests  # 發送請求
from bs4 import BeautifulSoup  # 解析頁面
import pandas as pd  # 存入csv數據
import os  # 判斷文件存在
from time import sleep  # 等待間隔
import random  # 隨機
import re  # 用正則表達式提取url

定義一個請求頭:

# 偽裝瀏覽器請求頭
headers = {
	"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36",
	"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
	"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
	"Connection": "keep-alive",
	"Accept-Encoding": "gzip, deflate, br",
	"Host": "www.baidu.com",
	# 需要更換Cookie
	"Cookie": "換成自己的cookie"
}

Cookie是個關鍵,如果不加Cookie,響應碼可能不是200,獲取不到數據,而且Cookie值是有有效期的,需要定期更換,如果發現返回無數據或響應碼非200,嘗試替換最新的Cookie。

怎麼獲取到Cookie呢?打開Chrome瀏覽器,訪問百度頁面,按F12進入開發者模式:

按照圖示順序,依次:

  1. 點擊Network,進入網路頁
  2. 點擊All,查看所有網路請求
  3. 選擇目標鏈接,和地址欄里的地址一致
  4. 查看Request Headers請求頭
  5. 查看請求頭裡的Cookie,直接右鍵,Copy value,粘貼到代碼里

然後,分析頁面請求地址:

wd=後面是搜索關鍵字"馬哥python說",pn=後面是10(規律:第一頁是0,第二頁是10,第三頁是20,以此類推),其他URL參數可以忽略。

然後,分析頁面元素,以搜索結果標題為例:

每一條搜索結果,都是class="result c-container new-pmd",下層結構里有簡介、鏈接等內容,解析內部子元素不再贅述。

所以根據這個邏輯,開發爬蟲代碼。

# 獲得每頁搜索結果
for page in range(v_max_page):
	print('開始爬取第{}頁'.format(page + 1))
	wait_seconds = random.uniform(1, 2)  # 等待時長秒
	print('開始等待{}秒'.format(wait_seconds))
	sleep(wait_seconds)  # 隨機等待
	url = 'https://www.baidu.com/s?wd=' + v_keyword + '&pn=' + str(page * 10)
	r = requests.get(url, headers=headers)
	html = r.text
	print('響應碼是:{}'.format(r.status_code))
	soup = BeautifulSoup(html, 'html.parser')
	result_list = soup.find_all(class_='result c-container new-pmd')
	print('正在爬取:{},共查詢到{}個結果'.format(url, len(result_list)))

其中,獲取到的標題鏈接,一般是這種結構:

http://www.baidu.com/link?url=7sxpKz_qoESU5b1BHZThKRAnXxPngB5kx1nZdUBCaXh7a4BgUgx9Zz-IqpeqDZTOIjvfY0u6ebnJdVWIfm5Tz_

這顯然是百度的一個跳轉前的地址,不是目標地址,怎麼獲取它背後的真實地址呢?

向這個跳轉前地址,發送一個請求,然後邏輯處理下:

def get_real_url(v_url):
	"""
	獲取百度鏈接真實地址
	:param v_url: 百度鏈接地址
	:return: 真實地址
	"""
	r = requests.get(v_url, headers=headers, allow_redirects=False)  # 不允許重定向
	if r.status_code == 302:  # 如果返回302,就從響應頭獲取真實地址
		real_url = r.headers.get('Location')
	else:  # 否則從返回內容中用正則表達式提取出來真實地址
		real_url = re.findall("URL='(.*?)'", r.text)[0]
	print('real_url is:', real_url)
	return real_url

如果響應碼是302,就從響應頭中的Location參數獲取真實地址。

如果是其他響應碼,就從響應內容中用正則表達式提取出URL真實地址。

把爬取到的數據,保存到csv文件:

df = pd.DataFrame(
			{
				'關鍵詞': kw_list,
				'頁碼': page_list,
				'標題': title_list,
				'百度鏈接': href_list,
				'真實鏈接': real_url_list,
				'簡介': desc_list,
				'網站名稱': site_list,
			}
		)
if os.path.exists(v_result_file):
	header = None
else:
	header = ['關鍵詞', '頁碼', '標題', '百度鏈接', '真實鏈接', '簡介', '網站名稱']  # csv文件標頭
df.to_csv(v_result_file, mode='a+', index=False, header=header, encoding='utf_8_sig')
print('結果保存成功:{}'.format(v_result_file))

to_csv的時候需加上選項(encoding='utf_8_sig'),否則存入數據會產生亂碼,尤其是windows用戶!

2.2 軟體界面

界面部分代碼:

# 創建主視窗
root = tk.Tk()
root.title('百度搜索爬蟲-定製化開發 | 馬哥python說')
# 設置視窗大小
root.minsize(width=850, height=650)

show_list_Frame = tk.Frame(width=800, height=450)  # 創建<消息列表分區>
show_list_Frame.pack_propagate(0)
show_list_Frame.place(x=30, y=120, anchor='nw')  # 擺放位置

# 滾動條
scroll = tk.Scrollbar(show_list_Frame)
# 放到Y軸豎直方向
scroll.pack(side=tk.RIGHT, fill=tk.Y)

2.3 日誌模塊

軟體運行過程中,會在同級目錄下生成logs文件夾,文件夾內會出現log文件,記錄下軟體在整個運行過程中的日誌,方便長時間運行、無人值守,出現問題後的debug。

部分核心代碼:

class Log_week():
    def get_logger(self):
        self.logger = logging.getLogger(__name__)
        # 日誌格式
        formatter = '[%(asctime)s-%(filename)s][%(funcName)s-%(lineno)d]--%(message)s'
        # 日誌級別
        self.logger.setLevel(logging.DEBUG)
        # 控制台日誌
        sh = logging.StreamHandler()
        log_formatter = logging.Formatter(formatter, datefmt='%Y-%m-%d %H:%M:%S')
        # info日誌文件名
        info_file_name = time.strftime("%Y-%m-%d") + '.log'
        # 將其保存到特定目錄,ap方法就是尋找項目根目錄,該方法博主前期已經寫好。
        case_dir = r'./logs/'
        info_handler = TimedRotatingFileHandler(filename=case_dir + info_file_name,
                                                when='MIDNIGHT',
                                                interval=1,
                                                backupCount=7,
                                                encoding='utf-8')
        self.logger.addHandler(sh)
        sh.setFormatter(log_formatter)
        self.logger.addHandler(info_handler)
        info_handler.setFormatter(log_formatter)
        return self.logger

三、軟體運行演示

演示視頻:
【爬蟲GUI演示】用python爬百度搜索,並開發成exe桌面軟體!


我是 @馬哥python說,持續分享python乾貨!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 MQ(Message Queue)就是消息隊列,其有點有很多:解耦、非同步、削峰等等,本文來聊一下RabbitMQ的一些概念以及使用。 RabbitMq 案例 Springboot整合RabbitMQ簡單案例 基本概念 Exchange:消息交換機,它指定消息按什麼規則,路由到哪個隊列。 Que ...
  • 使用mybatis-plus批量插入的時候報錯信息為:com.alibaba.druid.sql.parser.ParserException: syntax error, expect ')', pos 40, line 1, column 41, token EOF 排查sql日誌發現生成的sq ...
  • 什麼是數組? 官方定義:數組(Array)是有序的元素序列。 簡單來說:可以把數組想象成一個線性數據結構,用來裝東西的,每個東西有自己的編號,並且編號是從0 開始(重點) 直接來看語法: 數據類型 [] 標識符(自己取的名字) = new 數據類型 [數組裡元素個數] 或者 數據類型 [] 標識符( ...
  • 接上篇: 通過位元組碼,我們瞭解了class文件的結構 通過運行數據區,我們瞭解了jvm內部的記憶體劃分及結構 接下來,讓我們看看,位元組碼怎麼進入jvm的記憶體空間,各自進入那個空間,以及怎麼跑起來。 4.1 載入 4.1.1 概述 類的載入就是將class文件中的二進位數據讀取到記憶體中,然後將該位元組流所 ...
  • 主要推到了極化碼編碼矩陣生成迭代方式,並針對遞歸方法和按位生成(硬體生成不適用遞歸方案)的方法用matlab實現。 通道組合 W表示原始B-DMC通道。 下圖是兩個通道組合的例子。 長度為2的通道組合模型 長度為4的通道組合模型 長度為N/2與N的通道組合形式 G的推導及性質 G公式推導 編碼矩陣生 ...
  • 對於緩存容器而言,容量限制與數據淘汰是兩個基礎且核心的關鍵點,也是實際使用的時候使用頻率最高的特性。本篇在上一文基礎上深入解讀下Guava Cache中的容量限制與數據淘汰策略的實現與使用約束。 ...
  • Spring,作為 Java EE 的事實規範,在2022年11月16日發佈了最新的 6.0.0 GA 版本。這個版本是框架後續新生代的初始版本,擁抱持續創新的 OpenJDK 和 Java 生態。新的版本以 Java 17+ 作為 baseline,並遷移至 Jakarta EE 9+(即,使用 ...
  • 作者:寧海翔 1 前言 對象拷貝,是我們在開發過程中,繞不開的過程,既存在於Po、Dto、Do、Vo各個表現層數據的轉換,也存在於系統交互如序列化、反序列化。 Java對象拷貝分為深拷貝和淺拷貝,目前常用的屬性拷貝工具,包括Apache的BeanUtils、Spring的BeanUtils、Cgli ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...