c 抓取网页数据(Colly学习笔记(三)——爬虫框架,抓取动态页面 )

优采云 发布时间: 2022-04-12 10:28

  c 抓取网页数据(Colly学习笔记(三)——爬虫框架,抓取动态页面

)

  Colly 学习笔记(三) - 爬虫框架,抓取动态页面

  Colly学习笔记(一)-爬虫框架,捕捉中金行业市盈率数据

  Colly学习笔记(二)-爬虫框架,抓取下载数据

  Colly学习笔记(三) - 爬虫框架,抓取动态页面数据

  前两章主要讨论静态数据的爬取。我们只需要将网页地址栏中的url传递给get请求,就可以轻松获取网页的数据。但是,有些网页是动态页面。我们传递网页的源代码。翻页时找不到数据,网址也没有变化。此时无法获取数据。比如下图,通过开发者工具,查看网页源码,发现虽然URL相同,但内容不同。此时需要找到动态页面对应的URL,才能抓取数据。

  

  查看页面真实URL的方法如下:

  点击分页按钮找到对应的URL(具体步骤如图)

  

  通过postman查看和排除无效参数

  #动态URL原始参数

http://query.sse.com.cn/security/stock/getStockListData2.do?&jsonCallBack=jsonpCallback49711&isPagination=true&stockCode=&csrcCode=&areaName=&stockType=1&pageHelp.cacheSize=1&pageHelp.beginPage=3&pageHelp.pageSize=25&pageHelp.pageNo=3&pageHelp.endPage=31&_=1609296745917

#postman调试优化后的参数

http://query.sse.com.cn/security/stock/getStockListData2.do?stockType=1&pageHelp.cacheSize=1&pageHelp.beginPage=3&pageHelp.pageSize=25&pageHelp.pageNo=3

  postman 视图如下图

  

  写colly代码抓取流程

   //finish

c.OnScraped(func(r *colly.Response) {

//解析Json

var item PageResult

err := json.Unmarshal(r.Body, &item)

if err != nil {

receiver.MLog.GetLogHandle().WithFields(log.Fields{"err":err,"res":string(r.Body)}).Error("Receive Error ")

//若返回系统繁忙,则等一段时间重新访问

if strings.Contains(string(r.Body),"error"){

c.Visit(url)

}

}

//

if len(item.Result) > 1{

res = append(res,&item)

receiver.MLog.GetLogHandle().WithFields(log.Fields{"item":item}).Info("Receive message ")

return

}

//第一次只取一条是为了获取所有的A股总数,然后重新一次获取到所有数据,无需多次分页

SubUrl := "http://query.sse.com.cn/security/stock/getStockListData2.do?stockType=1&pageHelp.cacheSize=1&pageHelp.beginPage=1&pageHelp.pageSize="

SubUrl += strconv.Itoa(item.Page.Total)

c.Visit(SubUrl)

})

  结果:

  

  完整代码如下:

  package main

import (

"encoding/json"

"fmt"

"github.com/gocolly/colly"

log "github.com/sirupsen/logrus"

"strconv"

"strings"

)

type pageHelp struct {

Total int `json:"total"`

}

type pageResult struct {

CompanyAbbr string `json:"COMPANY_ABBR"`

CompanyCode string `json:"COMPANY_CODE"`

EnglishAbbr string `json:"ENGLISH_ABBR"`

ListingTime string `json:"LISTING_DATE"`

MoveTime string `json:"QIANYI_DATE"`

}

type PageResult struct {

AreaName string `json:"areaName"`

Page pageHelp `json:"pageHelp"`

Result []pageResult `json:"result"`

StockType string `json:"stockType"`

}

func (receiver Collector) ScrapeJs(url string) (error,[]*PageResult) {

receiver.MLog.GetLogHandle().WithFields(log.Fields{"URL":url}).Info("URL...")

c := colly.NewCollector(colly.UserAgent(RandomString()),colly.AllowURLRevisit())

c.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36"

res := make([]*PageResult, 0)

c.OnRequest(func(r *colly.Request) {

//r.Headers.Set("User-Agent", RandomString())

r.Headers.Set("Host", "query.sse.com.cn")

r.Headers.Set("Connection", "keep-alive")

r.Headers.Set("Accept", "*/*")

r.Headers.Set("Origin", "http://www.sse.com.cn")

//关键头 如果没有 则返回 错误

r.Headers.Set("Referer", "http://www.sse.com.cn/assortment/stock/list/share/")

r.Headers.Set("Accept-Encoding", "gzip, deflate")

r.Headers.Set("Accept-Language", "zh-CN,zh;q=0.9")

receiver.MLog.GetLogHandle().WithFields(log.Fields{"Request":fmt.Sprintf("%+v",*r),"Headers":fmt.Sprintf("%+v",*r.Headers)}).Info("Begin Visiting...")

})

c.OnError(func(_ *colly.Response, err error) {

receiver.MLog.GetLogHandle().WithFields(log.Fields{"error":err}).Info("Something went wrong:")

})

c.OnResponse(func(r *colly.Response) {

receiver.MLog.GetLogHandle().WithFields(log.Fields{"Headers":r.Headers}).Info("Receive Header")

})

//scraped item from body

//finish

c.OnScraped(func(r *colly.Response) {

var item PageResult

err := json.Unmarshal(r.Body, &item)

if err != nil {

receiver.MLog.GetLogHandle().WithFields(log.Fields{"err":err,"res":string(r.Body)}).Error("Receive Error ")

if strings.Contains(string(r.Body),"error"){

c.Visit(url)

}

}

if len(item.Result) > 1{

res = append(res,&item)

receiver.MLog.GetLogHandle().WithFields(log.Fields{"item":item}).Info("Receive message ")

return //结束递归

}

SubUrl := "http://query.sse.com.cn/security/stock/getStockListData2.do?stockType=1&pageHelp.cacheSize=1&pageHelp.beginPage=1&pageHelp.pageSize="

SubUrl += strconv.Itoa(item.Page.Total)

c.Visit(SubUrl)

})

c.Visit(url)

return nil,res

}

func (receiver Collector) ScrapeJsTest() error {

//第一次只获取一条数据目的是为了获取数据总条数,下次递归拼接URL一次获取所有数据

UrlA := "http://query.sse.com.cn/security/stock/getStockListData2.do?stockType=1&pageHelp.cacheSize=1&pageHelp.pageSize=1&pageHelp.beginPage=1"

receiver.ScrapeJs(UrlA)

return nil

}

func main() {

var c Collector

c.MLog=receiver.MLog

c.ScrapeJsTest()

return

}

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线