一、前言
1、愛漢服 去看看
2、這個小姐姐在這裏哈
【漢服美景】是誰把春光剪成一樹繁花?去看看
二、起因
1、看到一位博主寫了一篇python爬取漢服圖片的博文
2、精美漢服,送女友必備,python百行代碼帶你玩進漢服圈! 去看看
3、我估摸着,python已經有人寫了,那我就用go來實現一下吧:思路都差不多了,就是語法有點區別
三、思路講解
1、除了入口函數main(),有6個函數,他們的分工明確。
- main():入口函數
2、其他函數
1)、everyPage():處理每一頁的數據
- for循環處理每一頁的數據,獲取到當前頁的html(getHtmlByUrl()方法獲取url的html),正則匹配每篇文章的detailUrl(文章鏈接)和title(文章標題)
2)、everyArticle():處理每一篇文章的數據
- 根據文章的標題:創建名爲標題名的文件夾存放該篇文章的圖片(createDir()方法創建文件夾)
- 根據文章的鏈接:獲取文章的html(getHtmlByUrl()方法獲取url的html)。正則匹配到該文章的的所有圖片,然後把圖片下載到本地(saveFile()方法)。
- 把文章的標題和文章的鏈接記錄日誌(logger()記錄日誌)
3)、getHtmlByUrl():根據url地址返回string類型的html字符串
- 根據url鏈接返回html字符串,如果異常則返回空字符串
4)、createDir():根據文件夾的名字遞歸創建文件夾
5)、saveFile():保存圖片到本地
- 根據圖片的url獲取圖片的內容(getHtmlByUrl()方法獲取url的html
- 把string轉爲[]byte),存到本地。
6)、logger():存日誌文件
- 記錄日誌,如果日誌文件不存在則創建,文件的內容問追加模式(os.O_APPEND),每次調用之前的內容不會被清空。
四、代碼
package main
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"regexp"
"strconv"
"strings"
)
//入口函數
func main() {
startPage := 1 //開始頁
//endPage := 125
endPage := 3 //結束頁
//入口頁 http://www.aihanfu.com/zixun/tushang-1/
//結束頁 http://www.aihanfu.com/zixun/tushang-125/
//不難看出,目前是總共有125頁,那就來一個循環,從[1, 125]頁,遍歷每頁的數據
// 也可以動態獲取最後一頁(125):根據第一頁的html內容定位到最後一頁的值(125)
everyPage(startPage, endPage)
}
//處理每一頁的數據
func everyPage(startPage int, endPage int) {
url := "http://www.aihanfu.com/zixun/tushang-"
fmt.Println("開始處理...")
for page := startPage; page <= endPage; page++{ //循環每一頁的數據
fmt.Printf("處理第 [ %d ] 頁的數據\n", page)
pageUrl := url + strconv.Itoa(page) //每頁pageUrl拼接 = url + page轉字符串
html := getHtmlByUrl(pageUrl) //獲取當前頁的html內容
if html == "" { //html爲空,繼續下一頁
continue
}
//單篇文章的html如下,我們可以寫匹配語句匹配(標題,鏈接)了
//<h3 class="yh"><a target="_blank" href="http://www.aihanfu.com/wen/8332/">【漢服美景】天地之間,你是另一種絕色</a></h3>
pattern := "<h3 class=\"yh\"><a target=\"_blank\" href=\"(.*?)\">([^<]+)</a>" //注意原文中"_blank"是雙引號就要寫爲雙引號,不能寫成單引號,要用轉義字符轉一下
compile := regexp.MustCompile(pattern)
result := compile.FindAllStringSubmatch(html, -1) //正則匹配,結果爲 [][]string數組
if result == nil { //匹配失敗,繼續下一個匹配
continue
}
//循環獲取每一篇文章的內容
for key, value := range result{ //循環 [][]string數組
fmt.Printf("處理第 [ %d ] 頁 第 [%d] 篇文章的數據\n", page, (key+1))
detailUrl := value[1] //文章詳情頁鏈接
title := value[2] //文章標題
everyArticle(detailUrl, title) //處理每一篇文章
logger(title + " - " + detailUrl, "log.txt") //記錄日誌
}
}
fmt.Println("處理完成!!!")
}
//處理每一篇文章的數據
func everyArticle(url string, title string) {
html := getHtmlByUrl(url) //獲取文件的詳情
if html == "" {
return
}
//詳情頁一張圖片的Html內容如下,我們可以寫匹配的語句了
//<figure class="image img_wrap"><img src='http://static.aihanfu.net/uploadfile/2020/0304/20200304115441875.png' /></figure>
pattern := "<figure class=\"image img_wrap\"><img src='(.*?)' /></figure>"
compile := regexp.MustCompile(pattern)
result := compile.FindAllStringSubmatch(html, -1)
if result == nil { //匹配失敗,繼續下一個匹配
return
}
dir := createDir(title) //根據標題名創建文件夾
//循環獲取每一張圖片的內容
for _, value := range result{
imageUrl := value[1] //圖片鏈接
//設置文件名:獲取 http://static.aihanfu.net/uploadfile/2020/0520/20200520112218848.jpeg 的 20200520112218848.jpeg 作爲文件名
lastEqIndex := strings.LastIndex(imageUrl, "/")
fileName := imageUrl[lastEqIndex+1:] //最後一個/後面的內容
savePath := dir + "/" + fileName //保存到本地的地址:地址 + / + 圖片名
saveFile(imageUrl, savePath) //圖片下載操作
}
return
}
//根據url獲取html,並轉爲string
func getHtmlByUrl(url string) string{
html := ""
resp, err := http.Get(url)
if err == nil {
body, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err == nil {
html = string(body) //byte轉爲string
}
}
return html
}
//創建名爲dirName的文件夾,用於存放該文章的圖片
func createDir(dirName string) string{
dir := "./image/" + dirName //創建文件夾時,可能因爲文件名含有非法字符(\ / : * ? " < > |)非法而報錯
//如果文件夾不存在,則創建
_, err := os.Stat(dir)
if err != nil {
//os.Mkdir(dir, os.ModePerm) //創建單個文件夾
os.MkdirAll(dir, os.ModePerm) //遞歸創建文件夾
}
return dir
}
//保存文件操作
func saveFile(pictureUrl string, savePath string){
//判斷文件是否存在,如果存在,說明已經下載了,直接return,下載下一張圖片
_, err := os.Stat(savePath)
if err == nil {
fmt.Printf("圖片已下載 [ %s ] - [ %s ]\n", pictureUrl, savePath)
return
}
html := getHtmlByUrl(pictureUrl)
if html == ""{
fmt.Printf("圖片獲取失敗 [ %s ] - [ %s ] \n", pictureUrl, savePath)
return
}
out, _ := os.Create(savePath)
io.Copy(out, bytes.NewReader([]byte(html))) //string 轉爲[]byte
//循環結束,我們認爲圖片已經下載成功,控制檯輸出提示
fmt.Printf("圖片 [ %s ] 下載 [ %s ] 成功\n", pictureUrl, savePath)
}
//寫日誌
func logger(content string, logFile string){
//判斷文件是否存在,不存在則創建
_, err := os.Stat(logFile)
if err != nil {
os.Create(logFile)
}
//設置文件類型爲追加
file, err := os.OpenFile(logFile, os.O_APPEND|os.O_CREATE, 666)
if err != nil {
log.Fatalln("fail to open log file")
return
}
logger := log.New(file, "", log.LstdFlags) //設置日誌的記錄格式
logger.Println(content) //記錄(寫入)日誌
}
五、控制檯輸出
六、日誌
2020/05/22 17:42:33 【漢服少年】風起山巒,男兒有志在四方 - http://www.aihanfu.com/wen/8480/
2020/05/22 17:42:33 【漢服仕女】我見過青山如黛,卻遠不及你眉眼半分 - http://www.aihanfu.com/wen/8475/
2020/05/22 17:42:33 【漢服美景】雲中開寶剎,碧海信浮槎 - http://www.aihanfu.com/wen/8471/
2020/05/22 17:42:33 【漢服攝影】一瞥便是驚鴻,芳華亂了浮生 - http://www.aihanfu.com/wen/8467/
2020/05/22 17:42:34 【漢服美景】掬水月在手,弄花香滿衣 - http://www.aihanfu.com/wen/8465/
2020/05/22 17:42:34 【漢服攝影】少即是多,簡單而美 - http://www.aihanfu.com/wen/8464/
2020/05/22 17:42:34 【漢服攝影】月洞門裏走出一對小仙女 - http://www.aihanfu.com/wen/8462/
2020/05/22 17:42:34 【漢服夜景】春光浪屬夜櫻花 - http://www.aihanfu.com/wen/8459/
2020/05/22 17:42:34 【漢服私影】紅豆生南國 - http://www.aihanfu.com/wen/8456/
2020/05/22 17:42:34 【漢服少年】花間少年美如畫,行也思君,坐也思君 - http://www.aihanfu.com/wen/8454/
2020/05/22 17:42:35 【漢服攝影】湖海是你,日月星辰亦是你 - http://www.aihanfu.com/wen/8453/
2020/05/22 17:42:35 【漢服攝影】佛光 菩提並無樹,明鏡亦無臺 - http://www.aihanfu.com/wen/8452/
2020/05/22 17:42:35 【漢服攝影】頤和園 遇見古典之美 - http://www.aihanfu.com/wen/8451/
2020/05/22 17:42:35 【漢服攝影】千千素雪 不及 眉間一點紅 - http://www.aihanfu.com/wen/8449/
2020/05/22 17:42:35 【漢服攝影】敦煌美學,現代女子圖鑑 - http://www.aihanfu.com/wen/8446/
2020/05/22 17:42:35 【漢服攝影】大明少女與蘇州園林纔是絕配 - http://www.aihanfu.com/wen/8445/
2020/05/22 17:42:36 【漢服美景】夢裏有一場櫻雨,醒來去哪裏找這樣的仙境? - http://www.aihanfu.com/wen/8438/
2020/05/22 17:42:36 【漢服攝影】森林裏一抹藍色憂鬱 - http://www.aihanfu.com/wen/8435/
2020/05/22 17:42:36 【漢服攝影】旋轉,舞動的最美的時刻 - http://www.aihanfu.com/wen/8434/
2020/05/22 17:42:36 【漢服CP】四九青梅酸甜微醺!是心動的感覺~ - http://www.aihanfu.com/wen/8430/
2020/05/22 17:42:36 【漢服美景】微笑向暖,喜歡在春天裏流連 - http://www.aihanfu.com/wen/8414/
2020/05/22 17:42:37 【漢服攝影】詩經·國風·鄭風·野有蔓草 - http://www.aihanfu.com/wen/8408/
2020/05/22 17:42:37 【漢服攝影】塵事如潮人如水,只嘆江湖幾人回。 - http://www.aihanfu.com/wen/8407/
2020/05/22 17:42:37 【漢服美景】江南無所有,聊贈一枝春 - http://www.aihanfu.com/wen/8404/
2020/05/22 17:42:37 【漢服美景】是誰把春光剪成一樹繁花? - http://www.aihanfu.com/wen/8397/
2020/05/22 17:42:37 【漢服仕女】可嘆停機德,金簪雪裏埋 - http://www.aihanfu.com/wen/8396/
2020/05/22 17:42:37 【漢服美景】你和三月,都是春天 - http://www.aihanfu.com/wen/8391/
2020/05/22 17:42:37 【漢服仕女】張都尉,你的檀棋請查收~ - http://www.aihanfu.com/wen/8387/
2020/05/22 17:42:37 【漢服攝影】聊齋志異 · 嬰寧 - http://www.aihanfu.com/wen/8383/
2020/05/22 17:42:38 【漢服少年】陌上誰家年少足風流?啓禎兄弟的日常 - http://www.aihanfu.com/wen/8382/