Подпишитесь на официальный аккаунт " Программа Обезьяна без клетчатой рубашки " и ответьте " Хочу заниматься проституцией даром" , чтобы бесплатно получить 400 единиц информации.
Два дня назад маленький друг прислал редактору веб-сайт с большим количеством бесплатных книг.Как редактор «Проститутки Чжанцзян Бай», конечно, редактор должен оставить его себе. Поэтому я сделал простой анализ . Я чувствую, что ручная загрузка слишком медленная, а затем я просто написал обходчик, и эффект неплох . Основываясь на принципе, что дать человеку рыбу хуже, чем научить человека ловить рыбу, редактор поделится исходным кодом, чтобы вы могли поэкспериментировать самостоятельно. В то же время эта информация также будет обновляться в общедоступной учетной записи редактора.
Общая структура
Общая структура кода по-прежнему очень проста, в основном разделена на следующие шаги.
-
Получить все ссылки для скачивания согласно сканеру;
-
Обход всех ссылок, одиночная обработка;
-
URL-декодирование ссылки для создания китайского имени;
-
Определить, был ли загружен файл, по имени файла для обеспечения идемпотентности;
-
Загрузите файл и сохраните его;
Презентация результатов
Для демонстрации результатов в редакторе заранее загружены два файла, как показано ниже:
Подробный код
Ниже приведен подробный код, за исключением того, что xPach требует от нас анализа HTML-страницы, остальное не слишком сложно.
package main
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"os"
"path"
"strings"
"github.com/gocolly/colly"
)
const (
// 文件对应的域名,这里需要自己填写
fileDomain = "https://awesome-programming-books.github.io/"
// xPach 这里需要自己分析HTML页面
xPach = "div[class='is-mac'] > ul > li > a"
)
func main() {
urlList := getUrlList()
// 下载到本地
for _, fileUrl := range urlList {
fileName := returnFileName(fileUrl) // url解码
if fileName == "" {
fmt.Println("文件名称异常:", fileUrl)
}
if fileExist(fileName) {
fmt.Println("文件已经存在:", fileName)
continue
}
fmt.Println("开始下载,文件为:", fileName)
err := download(fileUrl, fileName)
if err != nil {
fmt.Println("下载失败,文件为:", fileName)
}
}
}
// 爬虫获取
func getUrlList() (urlList []string) {
urlList = make([]string, 0)
c := colly.NewCollector()
c.OnHTML(xPach, func(e *colly.HTMLElement) {
href := e.Attr("href")
// 去掉前缀,每个相对路径前面有【./】。需要去掉,后续拼接
href = strings.Replace(href, "./", "", 1)
urlList = append(urlList, fileDomain+href)
})
if err := c.Visit(fileDomain); err != nil {
return
}
return
}
// 生成文件名称
func returnFileName(fileUrl string) string {
fileName, err := url.QueryUnescape(fileUrl) // url解码
if err != nil {
fmt.Println("解析文件名失败,:", err)
return ""
}
fileName = strings.Replace(fileName, fileDomain, "", 1) // 去掉前缀
return path.Base(fileName) // 去掉目录,只保留最后
}
// 判断文件是否存在
func fileExist(path string) bool {
_, err := os.Lstat(path)
return !os.IsNotExist(err)
}
// 下载文件
func download(url, fileName string) (err error) {
fileName = path.Base(fileName)
fmt.Println(fileName)
out, err := os.Create(fileName)
defer out.Close()
resp, err := http.Get(url)
defer resp.Body.Close()
pix, err := ioutil.ReadAll(resp.Body)
_, err = io.Copy(out, bytes.NewReader(pix))
return
}
Благотворительный подарок
Пришло время долгожданных благ. На этот раз представлены 20 практических кейсов Golang.
Подпишитесь на официальный аккаунт " Программа Обезьяна без клетчатой рубашки " и ответьте " Хочу заниматься проституцией даром" , чтобы бесплатно получить 400 единиц информации.
Вся информация постоянно обновляется и предоставляется бесплатно. Друзья, пожалуйста, забирайте по мере необходимости.Конечно, если вы чувствуете себя хорошо, было бы лучше, если бы вы могли порекомендовать его своим друзьям.
Если у вас есть лучшие ресурсы, вы можете общаться друг с другом и совершенствоваться вместе. В то же время некоторые материалы взяты из Интернета, такие как вторжение и совместное удаление .
Рекомендовано в прошлом
Три подключения в один клик : я надеюсь пересылать , смотреть и делиться с другими студентами~
Публичный аккаунт : Программист, который не носит клетчатую рубашку