pointwin 发表于 2019-10-17 18:54

用go语言写的某书屋爬虫,有代码,有成品,大家笑纳

本帖最后由 pointwin 于 2019-10-17 18:56 编辑

来吾爱很久了,一直是伸手党,
今天写了一个书屋的爬虫,
献给爱读书的朋友们,
大家笑纳!

主要功能:爬取书名+下载网址+密码

该网站有两种下载页,
一个城通,一个百度云,
城通没有密码,百度云含密码
才学go语言,所以没有去重功能,
每次会重新新建txt文档,
之前爬好的数据,注意保存哦.

这是单线程的,多线程,
多线程,直接go working(i)即可.
再加入channel通知主go程退出即可.




上菜了...
居然不能超过1M.....

没办法上网盘吧...
爬虫地址:
https://pan.baidu.com/s/1ZxCjYeuEYoXZJgW87srpmw
提取码:aqn2
已爬的书籍:
如有侵权,联系删之
package main

import (
      "fmt"
      "io"
      "net/http"
      "os"
      "regexp"
      "strconv"
      "strings"
)
var count int
func main() {
      var start, end int
      fmt.Print("起始页(>=1):")
      fmt.Scan(&start)
      fmt.Print("终止页(>=起始页[适度爬取,太多小心IP被封哦]):")
      fmt.Scan(&end)

      //创建文件
      fc,err:=os.Create("BookList.txt")
      if err!=nil{
                fmt.Println("os.Create err",err)
                return
      }
      fc.Close()

      //循环读取每一页
      for i := start; i <= end; i++ {
                working(i)
      }
      fmt.Println("爬取完毕,马上闪开!!!")
}
func working(idx int) {

      //打开文件
      fo,err:=os.OpenFile("BookList.txt",os.O_APPEND,6)
      if err!=nil{
                fmt.Println("os.OpenFile err",err)
                return
      }
      defer fo.Close()

      url := "https://www.bukebook.cn/page/" + strconv.Itoa(idx)
      result, err := httpGet(url, idx)
      if err != nil {
                fmt.Println("检查网络,或者IP被封了...")
                return
      }

      //正则处理信息获得bookID
      //正则规则
      bookIDRule :=`class="greatwp-fp04-post-title"><a href="https://www.bukebook.cn/(+).html" rel="bookmark">`
      bookNameRule := `.html">《(?s:(.*?))</a></h2>`
      CTUrlRule := `<a class="ordown-button" href="(?s:(.*?))" target="_blank">城通网盘</a>`
      psdRule := `<strong>提取秘钥: </strong>(?s:(.*?))   </br>`

      allID:=regexpData(result, bookIDRule)
      for i,tmpID:=range allID{
                bookID:=tmpID
                //拼接下载页URL
                dlUrl:="https://www.bukebook.cn/wp-content/plugins/ordown/down.php?id="+bookID
                //访问下载页
                dlResult,err:=httpGet(dlUrl,i)
                if err!=nil{
                        fmt.Println("dl httpGet err",err)
                        return
                }
                //处理数据获取书名,下载地址及密码
                allBookName:=regexpData(dlResult,bookNameRule)
                allCTUrl:=regexpData(dlResult,CTUrlRule)
                allPsd:=regexpData(dlResult,psdRule)
                //fmt.Println(dlResult)
                for _,tmpBookName:=range allBookName{
                        bookName:=tmpBookName
                        //判断网盘类型
                        if strings.Contains(dlResult,"百度云盘"){
                              count++
                              //封装百度网盘URL
                              BDUrl:="https://www.bukebook.cn/wp-content/plugins/ordown/download1.php?id="+bookID
                              //获取网盘密码
                              for _,tmpPsd:=range allPsd{
                                        //存储书名及城通地址
                                        fo.Write([]byte(strconv.Itoa(count)+".《"+bookName+"\n"+BDUrl+""+tmpPsd+"\n"))
                                        fmt.Println("《"+bookName+" 完成\n")
                              }
                        }else{
                              count++
                              //获取城通网址
                              for _,tmpCTUrl:=range allCTUrl{
                                        //存储书名及城通地址
                                        fo.Write([]byte(strconv.Itoa(count)+".《"+bookName+"\n"+tmpCTUrl+"\n"))
                                        fmt.Println("《"+bookName+" 完成\n")
                              }

                        }
                }

      }

}
func regexpData(data, rule string) [][]string {
      reg := regexp.MustCompile(rule)
      return reg.FindAllStringSubmatch(data, -1)
}
func httpGet(url string, idx int) (result string, err error) {
      resp, err1 := http.Get(url)
      if err1 != nil {
                err = err1
                return
      }
      defer resp.Body.Close()
      buf := make([]byte, 4096)
      for {
                n, err2 := resp.Body.Read(buf)
                if n == 0 {
                        break
                }
                if err2 != nil && err2 != io.EOF {
                        err = err2
                        return
                }
                result += string(buf[:n])
      }
      return
}


追逐太阳 发表于 2019-10-17 19:04

go语言这个词现在听到的还不少。应该是一种趋势

梦幻妖精 发表于 2019-10-17 20:11

蟹蟹大佬!

laofanshu 发表于 2019-10-17 20:28

感谢分享

xttkmfss 发表于 2019-10-17 20:40

读书使我快乐,我自己都不相信我说了这个

zdnyp 发表于 2019-10-18 09:24

那个,原创区不是不允许发爬虫相关的么...

zdnyp 发表于 2019-10-18 09:25

zdnyp 发表于 2019-10-18 09:24
那个,原创区不是不允许发爬虫相关的么...

采集软件

mywebstudy 发表于 2019-10-18 09:38

不知道go语音发展如何,感觉谷歌好像不怎么上心

DKCopy 发表于 2019-10-18 09:48

是不是用Python 会更简单?{:1_918:}

zjgt 发表于 2019-10-20 00:58

学习学习
页: [1]
查看完整版本: 用go语言写的某书屋爬虫,有代码,有成品,大家笑纳