Golang 网络爬虫框架gocolly/colly(五)

2024-09-08 13:58

本文主要是介绍Golang 网络爬虫框架gocolly/colly(五),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

gcocolly+goquery可以非常好地抓取HTML页面中的数据,但碰到页面是由Javascript动态生成时,用goquery就显得捉襟见肘了。解决方法有很多种:
一,最笨拙但有效的方法是字符串处理,go语言string底层对应字节数组,复制任何长度的字符串的开销都很低廉,搜索性能比较高;
二,利用正则表达式,要提取的数据往往有明显的特征,所以正则表达式写起来比较简单,不必非常严谨;
三,使用浏览器控件,比如webloop;
四,直接操纵浏览器,比如chromedp。
一和二需要goquery提取javascript,然后再提取数据,速度非常快;三和四不需要分析脚本,在浏览器执行JavaScript生成页面后再提取,是比较偷懒的方式,但缺点是执行速度很慢,如果在脚本非常复杂、懒得分析脚本的情况下,牺牲下速度也是不错的选择。

不同的场景,做不同的选择。中证指数有限公司下载中心提供了行业市盈率下载,数据文件的Url在页面的脚本中,脚本简单且特征明显,直接用正则表达式的方式是最好的选择。

在这里插入图片描述
下载地址对应一段脚本

<a href="javascript:;" class="ml-20 dl download1">下载<i class="i_icon i_icon_rar ml-5"></i></a>
<script>
$(function() {
//切换
$('.hysyl_con').rTabs({
bind: 'click',
auto: false,
});
tabs($('.snav .tab_item'),$('.sCon .tab-con-item'));
tabs($('.snav2 .tab_item'),$('.sCon2 .tab-con-item'));
tabs($('.snav3 .tab_item'),$('.sCon3 .tab-con-item'));
$("#search_code1").on("click",function(){var csrc_code = $("#csrc_code1").val();if (csrc_code == '') {return false;}var url = "http://www.csindex.com.cn/zh-CN/downloads/industry-price-earnings-ratio-detail?date=2018-01-19&class=1&search=1&csrc_code="+csrc_code;$("#link_1").attr('href', url);document.getElementById("link_1").click();})$("#search_code2").on("click",function(){var csrc_code = $("#csrc_code2").val();if (csrc_code == '') {return false;}var url = "http://www.csindex.com.cn/zh-CN/downloads/industry-price-earnings-ratio-detail?date=2018-01-19&class=1&search=1&csrc_code="+csrc_code;$("#link_2").attr('href', url);document.getElementById("link_2").click();})
})
$(".download1").on("click",function(){var date = $(".date1").val();date = date.replace(/\-/g, '');if (date) {$("#link1").attr('href', 'http://115.29.204.48/syl/'+date+'.zip');document.getElementById("link1").click();}
});
$(".download2").on("click",function(){var date = $(".date2").val();date = date.replace(/\-/g, '');if (date) {$("#link2").attr('href', 'http://115.29.204.48/syl/csi'+date+'.zip');document.getElementById("link2").click();}
});
$(".download3").on("click",function(){var date = $(".date3").val();date = date.replace(/\-/g, '');if (date) {$("#link3").attr('href', 'http://115.29.204.48/syl/bk'+date+'.zip');document.getElementById("link3").click();}
});
</script>

在这里插入图片描述

点击下载时,为link1元素生成href属性,然后点击link1,这需要用gocolly+goquery提取date,然后获取服务器地址http://115.29.204.48/,根据获取文件的类型拼接字符串生成下载地址。

获取交易日期

sTime := ""
var bodyData []byte
c := colly.NewCollector()
c.OnResponse(func(resp *colly.Response) {bodyData = resp.Body
})
c.OnHTML("input[name=date]", func(el *colly.HTMLElement) {sTime = el.Attr("value")
})
err = c.Visit("http://www.csindex.com.cn/zh-CN/downloads/industry-price-earnings-ratio")
if err != nil {return
}

获取文件服务器地址,下载zip文件:

htmlDoc,err := goquery.NewDocumentFromReader(bytes.NewReader(bodyData))
if err != nil {return
}
scripts := htmlDoc.Find("script")
destScript := ""
for _,n := range scripts.Nodes {if n.FirstChild != nil {if strings.Contains(n.FirstChild.Data,"syl/csi") && strings.Contains(n.FirstChild.Data,".download2"){destScript = n.FirstChild.Databreak}}
}
re,err := regexp.Compile("http://[0-9]+.[0-9]+.[0-9]+.[0-9]+/syl/csi")
if err != nil {log.Fatal(err)
}
result := re.FindString(destScript)
pos := strings.LastIndex(result,"/")
parentUrl := result[0:pos+1]
link := parentUrl
sTime = strings.Replace(sTime,"-","",-1)
fileName := ""
if t == ZhengJjianHuiHangYePERatio {fileName = fmt.Sprintf("%s.zip",sTime)     link += fileNamefileName = "zjh"+fileName
}else if t == ZhongZhengHangYePERatio {fileName = fmt.Sprintf("csi%s.zip",sTime)link += fileName
}else {fileName = fmt.Sprintf("bk%s.zip",sTime)link += fileName
}
fmt.Println(link)
cli:=http.Client{}
resp,err := cli.Get(link)
if err != nil {return
}
defer resp.Body.Close()
fullFileName := fmt.Sprintf("%s/%s",filePath,fileName)
if resp.StatusCode == 200 {allBody,err := ioutil.ReadAll(resp.Body)if err != nil {return err}err = ioutil.WriteFile(fullFileName,allBody,0666)if err != nil {return err}
}else{err = fmt.Errorf("bad resp.%d",resp.StatusCode)return
}
err = archiver.Zip.Open(fullFileName, filePath)

在脚本里匹配服务器ip地址用 http://[0-9]+.[0-9]+.[0-9]+.[0-9]+/syl/csi,因为前后都有限定元素,所以写得比较简单;如果没有前后限定条件,设计正则表达式就得多费心了,复杂的正则表达式会吓跑很多人。不过没关系,稍微了解一些正则表达式的知识,就可以用在爬虫上了。

下载的文件是excel(.xls格式)的zip压缩包,解压缩操纵及xls读取后面再介绍。

原文链接:Golang 网络爬虫框架gocolly/colly 五 获取动态数据

这篇关于Golang 网络爬虫框架gocolly/colly(五)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1148299

相关文章

SSID究竟是什么? WiFi网络名称及工作方式解析

《SSID究竟是什么?WiFi网络名称及工作方式解析》SID可以看作是无线网络的名称,类似于有线网络中的网络名称或者路由器的名称,在无线网络中,设备通过SSID来识别和连接到特定的无线网络... 当提到 Wi-Fi 网络时,就避不开「SSID」这个术语。简单来说,SSID 就是 Wi-Fi 网络的名称。比如

Java实现任务管理器性能网络监控数据的方法详解

《Java实现任务管理器性能网络监控数据的方法详解》在现代操作系统中,任务管理器是一个非常重要的工具,用于监控和管理计算机的运行状态,包括CPU使用率、内存占用等,对于开发者和系统管理员来说,了解这些... 目录引言一、背景知识二、准备工作1. Maven依赖2. Gradle依赖三、代码实现四、代码详解五

Golang使用minio替代文件系统的实战教程

《Golang使用minio替代文件系统的实战教程》本文讨论项目开发中直接文件系统的限制或不足,接着介绍Minio对象存储的优势,同时给出Golang的实际示例代码,包括初始化客户端、读取minio对... 目录文件系统 vs Minio文件系统不足:对象存储:miniogolang连接Minio配置Min

Golang使用etcd构建分布式锁的示例分享

《Golang使用etcd构建分布式锁的示例分享》在本教程中,我们将学习如何使用Go和etcd构建分布式锁系统,分布式锁系统对于管理对分布式系统中共享资源的并发访问至关重要,它有助于维护一致性,防止竞... 目录引言环境准备新建Go项目实现加锁和解锁功能测试分布式锁重构实现失败重试总结引言我们将使用Go作

MyBatis框架实现一个简单的数据查询操作

《MyBatis框架实现一个简单的数据查询操作》本文介绍了MyBatis框架下进行数据查询操作的详细步骤,括创建实体类、编写SQL标签、配置Mapper、开启驼峰命名映射以及执行SQL语句等,感兴趣的... 基于在前面几章我们已经学习了对MyBATis进行环境配置,并利用SqlSessionFactory核

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

poj 3181 网络流,建图。

题意: 农夫约翰为他的牛准备了F种食物和D种饮料。 每头牛都有各自喜欢的食物和饮料,而每种食物和饮料都只能分配给一头牛。 问最多能有多少头牛可以同时得到喜欢的食物和饮料。 解析: 由于要同时得到喜欢的食物和饮料,所以网络流建图的时候要把牛拆点了。 如下建图: s -> 食物 -> 牛1 -> 牛2 -> 饮料 -> t 所以分配一下点: s  =  0, 牛1= 1~

cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个?

跨平台系列 cross-plateform 跨平台应用程序-01-概览 cross-plateform 跨平台应用程序-02-有哪些主流技术栈? cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个? cross-plateform 跨平台应用程序-04-React Native 介绍 cross-plateform 跨平台应用程序-05-Flutte

poj 3068 有流量限制的最小费用网络流

题意: m条有向边连接了n个仓库,每条边都有一定费用。 将两种危险品从0运到n-1,除了起点和终点外,危险品不能放在一起,也不能走相同的路径。 求最小的费用是多少。 解析: 抽象出一个源点s一个汇点t,源点与0相连,费用为0,容量为2。 汇点与n - 1相连,费用为0,容量为2。 每条边之间也相连,费用为每条边的费用,容量为1。 建图完毕之后,求一条流量为2的最小费用流就行了