go语言http编程与爬虫示例

一.前言

我们知道,用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.爬虫的工作流程:

  1. 明确URL (请求的地址,明确爬什么)
  2. 发送请求,获取响应数据
  3. 保存响应数据,提取有用信息
  4. 处理数据(存储、使用)
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)
	}
}


猜你喜欢

转载自blog.csdn.net/jin870132/article/details/93164378