抓取历年天气

使用goquery抓取天气的demo。数据量有点多。目前按省份存储天气数据。存储到csv文件中。


package main

import (
	"code.google.com/p/mahonia"
	"encoding/csv"
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"net/http"
	"os"
	"strings"
	"time"
)

var log = loger.Loger{
	Level: loger.DEBUG,}

const (
	YEAR      = 2013
	SleepTime = 100 //毫秒
)

func main() {
	sc,cc := GetCity()
	var weatherInfoAll []*WeaterInfo
	for key,value := range sc {
		filePath := fmt.Sprintf("%d%s.csv",YEAR,key)
		_,err := os.Stat(filePath)
		if err == nil {
			continue
		}
		weatherInfoAll = make([]*WeaterInfo,100000)
		for _,city := range value {
			name := cc[city]
			log.Debug("get ",key,city)
			client := &http.Client{}
			weatherInfoYear := GetWeather(client,city,name)
			weatherInfoAll = append(weatherInfoAll,weatherInfoYear...)
		}
		SaveToCSV(key,weatherInfoAll)
	}
}

//返回数据为省份=>城市名  城市名=>拼音.html
func GetCity() (sc map[string][]string,cc map[string]string) {
	url := "http://www.tianqihoubao.com/lishi/"
	request,err := http.NewRequest("GET",url,nil)
	if err != nil {
		log.Log(err)
		return
	}
	request.Header.Add("User-Agent","Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML,like Gecko) Ubuntu Chromium/39.0.2171.65 Chrome/39.0.2171.65 Safari/537.36")
	request.Header.Add("referer","http://www.tianqihoubao.com/")
	resp,err := http.DefaultClient.Do(request)
	if err != nil {
		log.Log(err)
		return
	}
	document,err := goquery.NewDocumentFromResponse(resp)
	if err != nil {
		log.Log(err)
		return
	}
	gbk := mahonia.NewDecoder("gbk")
	sc = make(map[string][]string)
	cc = make(map[string]string)
	document.Find(".citychk").Find("dl").Each(func(index int,s *goquery.Selection) {
		province := gbk.ConvertString(s.Find("dt").Find("b").Text())
		citys := make([]string,20)
		s.Find("dd").Find("a").Each(func(index int,se *goquery.Selection) {
			uri,exists := se.Attr("href")
			if !exists {
				return
			}
			name := gbk.ConvertString(se.Text())
			uri = strings.Replace(uri,".html","",-1)
			citys = append(citys,name)
			cc[name] = uri
		})
		sc[province] = citys
	})
	return
}

type WeaterInfo struct {
	Province string
	City     string
	Date     string
	Info     string
	Temp     string
	Wind     string
}

func GetWeather(client *http.Client,province,name string) []*WeaterInfo {
	baseUrl := fmt.Sprintf("http://www.tianqihoubao.com%s/month/%%s",name)
	weaterInfoYear := make([]*WeaterInfo,380)
	for i := 1; i <= 12; i++ {
		url := fmt.Sprintf(baseUrl,fmt.Sprintf("%d%02d.html",i))
		weaterInfos := GetWeatherInfo(client,url)
		weaterInfoYear = append(weaterInfoYear,weaterInfos...)
		time.Sleep(time.Millisecond * SleepTime)
	}
	return weaterInfoYear
}

func GetWeatherInfo(client *http.Client,url string) (weaterInfos []*WeaterInfo) {
	request,err := client.Do(request)
	if err != nil {
		log.Log(err)
		return
	}
	document,err := goquery.NewDocumentFromResponse(resp)
	if err != nil {
		log.Log(err)
		return
	}
	gbk := mahonia.NewDecoder("gbk")
	weaterInfos = make([]*WeaterInfo,31)
	document.Find("#content").Find("tbody").Find("tr").Each(func(index int,s *goquery.Selection) {
		//排除第一个
		if index == 0 {
			return
		}
		var date,info,temp,wind string
		s.Find("td").Each(func(index int,se *goquery.Selection) {
			if index == 0 {
				date = gbk.ConvertString(se.Find("a").Text())
			}
			if index == 1 {
				info = gbk.ConvertString(se.Text())
			}
			if index == 2 {
				temp = gbk.ConvertString(se.Text())
			}
			if index == 3 {
				wind = gbk.ConvertString(se.Text())
			}
		})
		weatherInfo := &WeaterInfo{
			Province: province,City:     city,Date:     date,Info:     info,Temp:     temp,Wind:     wind,}
		weaterInfos = append(weaterInfos,weatherInfo)
	})
	return
}

func SaveToCSV(file string,weatherInfos []*WeaterInfo) (err error) {
	filePath := fmt.Sprintf("%d%s.csv",file)
	_,err = os.Stat(filePath)
	if err == nil {
		return
	}
	f,err := os.Create(filePath)
	if err != nil {
		log.Log(err)
		return
	}
	defer f.Close()
	f.WriteString("\xEF\xBB\xBF")  //UTF-8
	w := csv.NewWriter(f)
	w.Write([]string{"省份","城市","日期","天气状况","气温","风力风向"})
	for i,weatherInfo := range weatherInfos {
		if i%1000 == 0 {
			w.Flush() //刷入文件
		}
		strs := []string{TrimSpace(weatherInfo.Province),TrimSpace(weatherInfo.City),TrimSpace(weatherInfo.Date),TrimSpace(weatherInfo.Info),TrimSpace(weatherInfo.Temp),TrimSpace(weatherInfo.Wind)}
		w.Write(strs)
	}
	w.Flush()
	return
}

func TrimSpace(value string) string {
	value = strings.Replace(value,"\n",-1)
	return strings.Replace(value," ",-1)
}

日志库删掉了,因为看起来有点不是很好。当然,也没有说这个代码好。只是临时写着东西。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


类型转换 1、int转string 2、string转int 3、string转float 4、用户结构类型转换
package main import s &quot;strings&quot; import &quot;fmt&quot; var p = fmt.Println func main() { p(&quot;Contains: &quot;, s.Contains(&quot;test&quo
类使用:实现一个people中有一个sayhi的方法调用功能,代码如下: 接口使用:实现上面功能,代码如下:
html代码: beego代码:
1、读取文件信息: 2、读取文件夹下的所有文件: 3、写入文件信息 4、删除文件,成功返回true,失败返回false
配置环境:Windows7+推荐IDE:LiteIDEGO下载地址:http://www.golangtc.com/downloadBeego开发文档地址:http://beego.me/docs/intro/ 安装步骤: 一、GO环境安装 二、配置系统变量 三、Beego安装 一、GO环境安装 根
golang获取程序运行路径:
Golang的文档和社区资源:为什么它可以帮助开发人员快速上手?
Golang:AI 开发者的实用工具
Golang的标准库:为什么它可以大幅度提高开发效率?
Golang的部署和运维:如何将应用程序部署到生产环境中?
高性能AI开发:Golang的优势所在
本篇文章和大家了解一下go语言开发优雅得关闭协程的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。1.简介本文将介绍首先为什么需要主...
这篇文章主要介绍了Go关闭goroutine协程的方法,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。1.简介本文将介绍首先为什么需要主动关闭gor...
本篇文章和大家了解一下go关闭GracefulShutdown服务的几种方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。目录Shutdown方法Regi...
这篇文章主要介绍了Go语言如何实现LRU算法的核心思想和实现过程,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。GO实现Redis的LRU例子常
今天小编给大家分享的是Go简单实现多租户数据库隔离的方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会...
这篇“Linux系统中怎么安装NSQ的Go语言客户端”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希
本文小编为大家详细介绍“怎么在Go语言中实现锁机制”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么在Go语言中实现锁机制”文章能帮助大家解决疑惑,下面...
今天小编给大家分享一下Go语言中interface类型怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考