前些日子参加了一个叫Advent of Code的编程大赛,每天一道题,快活似神仙。这每道题都有自己的拼图数据输入puzzle input,要做题就需要用到该数据,把数据复制过来感觉又太麻烦,于是就兴起写了一个直接从html读取数据的函数。

数据如下:

+12
-10
-4
-8
+18
-1
-13
...

查看标准库文档,发现net/html包可以做这个功能,其函数如下:

resp, err := http.Get("http://example.com/")
if err != nil {
// handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
// ...

然后调试,但并未有相关数据输出,在浏览器中检查元素发现该请求需要带cookie才能正确返回数据。直接使用http.Get()并不带有cookie,所以改用NewRequest使用指定的方法、网址和可选的主题创建并返回一个新的*Request。其函数如下:

client := &http.Client{}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Cookie", "name=value")
resp, err := client.Do(req) robots, err := ioutil.ReadAll(resp.Body) resp.Body.Close()//必须要关闭Body

ioutil.ReadAll()返回的是[]byte类型,入需要使用可以先将[]byte转换成string,Go语言初学者都会的类型转换语法:string(b),Go为了稳定性对于上述方法需要经过一些数据上的复制,一旦数据量过大,这个成本是难以忍受的。

所以为了让Go服帖,我们得用上unsafe包,unsafe包提供一些可以跳过Go语言类型安全限制的操作。看下面代码:

func BytesString(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}

我们取到[]byte的指针,Go会说*byte不是*string,但是我们有外挂unsafe.Pointer,所以Go就通过了,接着你很自在的把*byte转成了*string,因为reflect.StringHeaderreflect.SliceHeader的结构体只相差末尾一个字段。

类似的用法可以看Go语言黑魔法

接着用regexp包正则表达式FindAllString取出匹配的[]string数据使用,然后再用strconv.Atoi()进行转化就可以了。

Day1的题为求和,其代码如下:

package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"regexp"
"strconv"
"unsafe"
)
func BytesString(b []byte) string {//[]byte 转string
return *(*string)(unsafe.Pointer(&b))
}
func getPuzzle(url string) string {//从网页抓取数据
client := &http.Client{}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Cookie", "session=53616c7xxx")
resp, err := client.Do(req)
robots, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
str := BytesString(robots)
return str
}
func sum(num []int) int {
sum := 0
for _, n := range num {
sum += n
}
return sum
}
func strtoint(str []string) []int {//string转int
num := make([]int, len(str))
for i := 0; i < len(str); i++ {
flag := str[i][0]
chafre, _ := strconv.Atoi(str[i][1:])
switch flag {
case '+':
num[i] = chafre
case '-':
num[i] = -chafre
}
}
return num
}
func main() {
change := getPuzzle("https://adventofcode.com/2018/day/1/input")
re := regexp.MustCompile("[+|-][0-9]*")//正则表达式
str := re.FindAllString(change, -1)
num := strtoint(str)
sum := sum(num)
fmt.Printf("sum is %d\n", sum)
}

如果有更好的方法,欢迎私信,哈哈哈···

最新文章

  1. Git初探--笔记整理和Git命令详解
  2. NDK 笔记(一)
  3. 敏捷软件开发vs传统软件开发
  4. NuGet学习笔记1——初识NuGet及快速安装使用
  5. 【Linux日志】系统日志及分析
  6. HDOJ 1856 More is better
  7. Hibernate学习之对象持久化
  8. jade的基本语法
  9. java微信平台,发源码
  10. 关于 struts2 Unable to load configuration. - action
  11. Jarvis OJ- [XMAN]level2/3_x64-Writeup——64位简单栈溢出
  12. Boosting 和梯度Boosting
  13. Springboot解决war包放到Tomcat服务器上404的特殊情况
  14. Android v7包下Toolbar和ActionBarActivity实现后退导航效果
  15. Android Studio 代码导航快捷键总结
  16. Cannot find config.m4. Make sure that you run &#39;/usr/local/php/bin/phpize&#39; in the top level source directory of the module的 解决方法
  17. Spring IOC和IOC容器
  18. 架构师养成记--31.Redis的几种类型
  19. php about session store db or cache
  20. coreseek mmseg分词配置和创建

热门文章

  1. python错误和异常(1)
  2. MySQL 数据库 -- 操作
  3. Microsoft Visual Studio 遇到了问题需要关闭
  4. MAC软件工具下载
  5. Django的视图流式响应机制
  6. domain是什么
  7. ArcFac_C#_DEMO开发
  8. js中this应用
  9. java 静态相关内容
  10. Apollo2.5摄像头安装