基于golang的爬虫系统

发布时间:2021-04-21编辑:RainNight阅读(931)

    基于golang的爬虫系统


    本代码基本功能实现、数据库操作,发送邮件和发送钉钉通知、定时任务、解析html


    最基础的代码体系、后期会完成log日志等功能 代码篇:

    ckage main
    
    import (
    	"fmt"
    	"github.com/PuerkitoBio/goquery"
    	_ "github.com/go-sql-driver/mysql"
    	"github.com/jmoiron/sqlx"
    	"github.com/jordan-wright/email"
    	"github.com/robfig/cron"
    	"io/ioutil"
    	"log"
    	"net/http"
    	"net/smtp"
    	"strings"
    	"time"
    )
    
    type News struct {
    	Id   int `db:"id"`
    	Title   string `db:"title"`
    	Banner  string `db:"banner"`
    	Url  string `db:"url"`
    	Author  string `db:"author"`
    	Content string `db:"content"`       
    	Article_date string `db:"article_date"`
    }
    
    // 获取http
    func analysisHttp(url string) string {
    
    	resp, err := http.Get(url)
    	if err != nil {
    		fmt.Println(err, "http的错误")
    	}
    
    	defer resp.Body.Close()
    
    	if resp.StatusCode != 200 {
    		log.Fatalf("status code error: %d %s", resp.StatusCode, resp.Status)
    	}
    
    	urlByte, _ := ioutil.ReadAll(resp.Body)
    
    	return string(urlByte)
    }
    
    //解析网址
    func getWebAdress(url string) {
    	urlStr := url
    	doc, _ := goquery.NewDocumentFromReader(strings.NewReader(urlStr))
    
    	tagsList := []News{}
    
    	timeUnix := time.Now().Format("2006-01-02 15:04:05")
    
    	doc.Find(".block .article-list").Each(func(i int, s *goquery.Selection) {
    		title := s.Find(".title a").Text()
    		href, _ := s.Find(".title a").Attr("href")
    		banner, _ := s.Find("img").Attr("src")
    
    		respes := analysisHttp(href)
    
    		contentInfo, _ := goquery.NewDocumentFromReader(strings.NewReader(respes))
    
    		author := contentInfo.Find(".wp #article_copyright .textcut").Text()
    
    		content, _ := contentInfo.Find("#article_content").Html()
    
    		tagsList = append(tagsList, News{Title: title, Url: href, Banner: banner,Author: author,Content: content,Article_date:timeUnix })
    	})
    
    	var news []News
    	for _,value := range tagsList {
    		// 查
    		selectErr := Db.Select(&news,"select id from tb_news where url=?",value.Url)
    
    		if selectErr != nil {
    			fmt.Println("exec failed, ", selectErr)
    			return
    		}
    
    		if news == nil{
    
    			r, err :=Db.Exec("insert into tb_news(title,banner,url,author,article_date,content)values(?,?,?,?,?,?)",value.Title,value.Banner,value.Url,value.Author,value.Article_date,value.Content)
    
    			if err != nil {
    				fmt.Println("exec failed, ", err)
    				return
    			}
    
    			id, idErr := r.LastInsertId()
    
    			if idErr != nil {
    				fmt.Println("exec failed, ", idErr)
    				return
    			}
    			fmt.Println("insert succ:", id)
    		}else{
    			log.Println("重复数据去重......")
    		}
    	}
    
    	e := email.NewEmail()
    	//设置发送方的邮箱
    	e.From = "18538187569@163.com"
    	// 设置接收方的邮箱
    	e.To = []string{"838690360@qq.com"}
    	// 设置主题
    	e.Subject = "爬虫运行报告"
    
    	//设置文件发送的内容
    	e.Text = []byte(timeUnix+"执行的爬虫报告......")
    	//设置服务器相关的配置
    	err := e.Send("smtp.163.com:25", smtp.PlainAuth("", "18538187569@163.com", "UIOHXCVLHWOEUDJQ", "smtp.163.com"))
    	if err != nil {
    		log.Fatal(err)
    	}
    	fmt.Println("执行成功")
    
    	defer Db.Close()
    }
    
    var Db *sqlx.DB
    
    func init()  {
    	database, err :=	sqlx.Open("mysql","root:1234567890@tcp(127.0.0.1:3306)/beego_blog")
    
    	if err != nil {
    		fmt.Println("open mysql failed,", err)
    		return
    	}
    	Db = database
    }
    
    // 业务逻辑
    func newsBusiness()  {
    
    	//timeUnix := time.Now().Format("2006-01-02 15:04:05")
    	//fmt.Println("定时请求接口.......,时间:"+timeUnix)
    	// 获取网址
    	getUrl := analysisHttp("https://linux.cn/news/")
    	getWebAdress(getUrl)
    }
    
    // 定时任务,可以设置具体的时间
    func timeNewsTask() {
    	// 每天凌晨0点执行一次:0 0 0 * * ?
    	//每隔5秒执行一次:*/5 * * * * ?
    	//每隔1分钟执行一次:0 */1 * * * ?
    	//每天23点执行一次:0 0 23 * * ?
    	//每天凌晨1点执行一次:0 0 1 * * ?
    	//每月1号凌晨1点执行一次:0 0 1 1 * ?
    	//在26分、29分、33分执行一次:0 26,29,33 * * * ?
    	//每天的0点、13点、18点、21点都执行一次:0 0 0,13,18,21 * * ?
    
    	spec := "0 0 0 * * ?"
    	c := cron.New(cron.WithSeconds()) # macOS下可以正常执行
    	c := cron.New() # 在Linux在可以正常执行原因需要在探索
    	c.AddFunc(spec,newsBusiness)
    	go c.Start()
    	defer c.Stop()
    	select {}
    }
    
    func main() {
    	timeNewsTask()
    }
    

关键字Golang

Collect from 雨夜的博客 雨夜的博客