一.前言
我们知道,用java做服务端的时候需要很多繁琐的配置,还需要开发工具关联tomcat等,golang相对而言就简单了很多.我们通过几个示例看一下golang怎么做http编程.
二.编写一个简单的web服务器
package main
import (
"net/http"
"fmt"
"os"
)
func OpenSendFile(fNmae string, w http.ResponseWriter) {
pathFileName := "C:/test" + fNmae
f, err := os.Open(pathFileName)
if err != nil {
fmt.Println("Open err:", err)
w.Write([]byte(" No such file or directory !"))
return
}
defer f.Close()
buf := make([]byte, 4096)
for {
n, _ := f.Read(buf) // 从本地将文件内容读取。
if n == 0 {
return
}
w.Write(buf[:n]) // 写到 客户端(浏览器)上
}
}
func myHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("客户端请求:", r.URL)
OpenSendFile(r.URL.String(), w)
}
func main() {
// 注册回调函数
http.HandleFunc("/", myHandler)
// 绑定监听地址
http.ListenAndServe("127.0.0.1:8000", nil)
}
三.爬虫示例
1.爬虫的定义:
网络爬虫(又被称为网页蜘蛛,网络机器人),是一种按照一定的规则自动地抓取万维网信息的程序。
简单来说,就是编写程序,模拟浏览器发送请求,获取到和浏览器一模一样的数据。因此,我们能获取的是浏览器能够接收到的数据。
2.爬虫的工作流程:
- 明确URL (请求的地址,明确爬什么)
- 发送请求,获取响应数据
- 保存响应数据,提取有用信息
- 处理数据(存储、使用)
package main
import (
"fmt"
"io"
"net/http"
"regexp"
"strconv"
"strings"
)
var baseUrl = "https://www.qidian.com/rank/yuepiao?page=";
var ch = make(chan int)
/**
测试网络爬虫
*/
func main() {
//
ch := make(chan int)
for i := 0; i < 5; i++ {
go toSpider(i, ch)
}
for i := 0; i < 5; i++ {
fmt.Println("第", <-ch, "读取完毕")
}
}
func toSpider(page int, ch chan int) {
fmt.Println("开始读取第" + strconv.Itoa(page) + "页")
url := baseUrl
result := httpGet(url)
toSave(result)
ch <- page
}
func toSave(result string){
//定义正则匹配关系
//这里随便写了一点正则匹配规则,正则表达式不在本次讨论范围内
ret := regexp.MustCompile(`<h4>(?s:(.*?))</h4>`)
//-1匹配所有字符串
alls :=ret.FindAllStringSubmatch(result,-1)
for _, tmpTitle := range alls {
title := tmpTitle[1]
title = strings.Replace(title, "\t", "", -1)
fmt.Println(title)
break
}
}
/**
get请求
*/
func httpGet(url string) (result string) {
resp, err := http.Get(url)
defer resp.Body.Close()
doError("连接错误", err)
buf := make([]byte, 4096)
for {
n, err := resp.Body.Read(buf)
doError("读取错误", err)
//n=0读取完毕
if n == 0 {
break
}
result += string(buf[:n])
}
return result
}
/**
错误处理
*/
func doError(name string, err error) {
if (err != nil && err != io.EOF) {
fmt.Println(name, ":", err)
}
}