咱們今天要爬取的網址爲:https://www.zhiliti.com.cn/html/luoji/list7_1.htmlhtml
即獲取全部的題目以及答案。python
分析:
1,首先查看該網站的結構。瀏覽器
分析網頁後能夠獲得:服務器
咱們須要的內容是在該網頁<li>標籤下,詳細內容連接在<small>的<a>的href中。函數
可是這樣咱們最多隻能獲取這一頁的內容網站
彆着急編碼
咱們點擊第二頁看一下目標網址有什麼變化url
咱們發現目標網址最後的數字變成了2spa
再看一下最後一頁3d
咱們能夠分析出最後那個數字即第幾頁,因此咱們待會能夠直接用一個for循環拼接字符串便可。
分析詳細頁面:
咱們隨便點擊進入一個閱讀全文
一樣分析網頁結構。
發現咱們要的內容在一個塊<div class="info-zi mb15"/>的<p>標籤中,咱們在看一下其餘題是否是也是這樣的
很明顯是這樣的,因此咱們只須要獲取class爲info-zi mb15下的<p>標籤下的內容便可。
因此咱們接下來開始實現。
Let's Go
def getall(): for i in range(1,31,1): getalldoc(i)
i表示第i頁,一共30頁因此i從1變化到30,每次增長1。
#獲取目標網址第幾頁 def getalldoc(ii): #字符串拼接成目標網址 testurl = "https://www.zhiliti.com.cn/html/luoji/list7_"+str(ii)+".html" #使用request去get目標網址 res = requests.get(testurl,headers=headers) #更改網頁編碼--------不改會亂碼 res.encoding="GB2312" #建立一個BeautifulSoup對象 soup = BeautifulSoup(res.text,"html.parser") #找出目標網址中全部的small標籤 #函數返回的是一個list ans = soup.find_all("small") #用於標識問題 cnt = 1 #先建立目錄 mkdir("E:\\Python爬取的文件\\問題\\第" + str(ii) + "頁\\") for tag in ans: #獲取a標籤下的href網址 string_ans=str(tag.a.get("href")) #請求詳細頁面 #返回咱們須要的字符串數據 string_write = geturl(string_ans) #寫文件到磁盤 writedoc(string_write,cnt,ii) cnt = cnt+1 print("第",ii,"頁寫入完成")
先拼接處目標網頁url,而後調用request去請求,更改網頁編碼,使用BeautifulSoup對html文檔進行解析,找出全部<small>標籤,存入一個list,而後遍歷該list,獲取每個<small>標籤裏的<a>標籤的href屬性,並將其轉換爲字符串string_ans。
獲得詳細頁面的url以後咱們調用geturl(自定義函數下面講解)返回咱們所須要的題目字符串,最後調用writedoc寫入文件。
#根據詳細頁面url獲取目標字符串 def geturl(url): #請求詳細頁面 r = requests.get(url, headers=headers) #改編碼 r.encoding = "GB2312" soup = BeautifulSoup(r.text, "html.parser") #找出類名爲 info-zi mb15 下的全部p標籤 ans = soup.find_all(["p", ".info-zi mb15"]) #用來儲存最後須要寫入文件的字符串 mlist = "" for tag in ans: #獲取p標籤下的string內容,並進行目標字符串拼接 mlist=mlist+str(tag.string) #返回目標字符串 return mlist
首先請求網頁構建一個BeautifulSoup對象,篩選出class=info-zi mb15的對象下的<p>標籤內容,返回類型爲list,遍歷list,將每一個item的string拼接到目標字符串並返回。
#寫文件 def writedoc(ss, i,ii): #打開文件 #編碼爲utf-8 with open("E:\\Python爬取的文件\\問題\\第" + str(ii) + "頁\\"+"問題" + str(i) + ".txt", 'w', encoding='utf-8') as f: #寫文件 f.write(ss) print("問題" + str(i) + "文件寫入完成" + "\n")
def mkdir(path): # 去除首位空格 path = path.strip() # 去除尾部 \ 符號 path = path.rstrip("\\") # 判斷路徑是否存在 # 存在 True # 不存在 False isExists = os.path.exists(path) # 判斷結果 if not isExists: # 若是不存在則建立目錄 # 建立目錄操做函數 os.makedirs(path) return True else: # 若是目錄存在則不建立,並提示目錄已存在 return False
import requests from bs4 import BeautifulSoup import os # 服務器反爬蟲機制會判斷客戶端請求頭中的User-Agent是否來源於真實瀏覽器,因此,咱們使用Requests常常會指定UA假裝成瀏覽器發起請求 headers = {'user-agent': 'Mozilla/5.0'} #寫文件 def writedoc(ss, i,ii): #打開文件 #編碼爲utf-8 with open("E:\\Python爬取的文件\\問題\\第" + str(ii) + "頁\\"+"問題" + str(i) + ".txt", 'w', encoding='utf-8') as f: #寫文件 f.write(ss) print("問題" + str(i) + "文件寫入完成" + "\n") #根據詳細頁面url獲取目標字符串 def geturl(url): #請求詳細頁面 r = requests.get(url, headers=headers) #改編碼 r.encoding = "GB2312" soup = BeautifulSoup(r.text, "html.parser") #找出類名爲 info-zi mb15 下的全部p標籤 ans = soup.find_all(["p", ".info-zi mb15"]) #用來儲存最後須要寫入文件的字符串 mlist = "" for tag in ans: #獲取p標籤下的string內容,並進行目標字符串拼接 mlist=mlist+str(tag.string) #返回目標字符串 return mlist #獲取目標網址第幾頁 def getalldoc(ii): #字符串拼接成目標網址 testurl = "https://www.zhiliti.com.cn/html/luoji/list7_"+str(ii)+".html" #使用request去get目標網址 res = requests.get(testurl,headers=headers) #更改網頁編碼--------不改會亂碼 res.encoding="GB2312" #建立一個BeautifulSoup對象 soup = BeautifulSoup(res.text,"html.parser") #找出目標網址中全部的small標籤 #函數返回的是一個list ans = soup.find_all("small") #用於標識問題 cnt = 1 #先建立目錄 mkdir("E:\\Python爬取的文件\\問題\\第" + str(ii) + "頁\\") for tag in ans: #獲取a標籤下的href網址 string_ans=str(tag.a.get("href")) #請求詳細頁面 #返回咱們須要的字符串數據 string_write = geturl(string_ans) #寫文件到磁盤 writedoc(string_write,cnt,ii) cnt = cnt+1 print("第",ii,"頁寫入完成") def mkdir(path): # 去除首位空格 path = path.strip() # 去除尾部 \ 符號 path = path.rstrip("\\") # 判斷路徑是否存在 # 存在 True # 不存在 False isExists = os.path.exists(path) # 判斷結果 if not isExists: # 若是不存在則建立目錄 # 建立目錄操做函數 os.makedirs(path) return True else: # 若是目錄存在則不建立,並提示目錄已存在 return False def getall(): for i in range(1,31,1): getalldoc(i) if __name__ == "__main__": getall()
四,運行結果
五,總結
通常網頁的編碼爲utf-8編碼,可是這個網頁就不同編碼爲GB2312,我第一次請求返回的是亂碼,若是python向一個不存在的目錄進行寫文件會報錯,因此寫文件以前要先判斷路徑是否正確存在,不存在就要建立路徑,請求頭請使用下面這個
# 服務器反爬蟲機制會判斷客戶端請求頭中的User-Agent是否來源於真實瀏覽器,因此,咱們使用Requests常常會指定UA假裝成瀏覽器發起請求 headers = {'user-agent': 'Mozilla/5.0'}