go语言采集的问题

ecshop528 2014-09-14 12:18:08
func InsertInfo(info map[string]string, session *mgo.Session) {
db := session.DB("test") //数据库名称
collection := db.C("a") //如果该集合已经存在的话,则直接返回

//t := struct{ Url string }{}
//collection.Find(bson.M{}).One(&t)
//fmt.Println(t)
count,_ := collection.Find(nil).Count()
pagecount := count/100
t := struct{ Url string }{}
for i:=0;i<=pagecount;i++ {
query := collection.Find(bson.M{}).Skip(i*100).Limit(100).Batch(2).Iter()
for query.Next(&t) {
go InsertMongo(collection,t.Url)
}
}

}

func InsertMongo(collection *mgo.Collection,url string) {
res1,err :=GetInfo("http://www.cndzys.com"+url)
if err == nil {
collection.Insert(bson.M{"title":res1["title"],"desc":res1["desc"]})
}
}


把代码分成这样 InsertMongo()函数独立出来。这样就采集不到数据.提示采集的内容为空,提示"获取远程内容为空"


如果合并成一个函数

func InsertInfo(info map[string]string, session *mgo.Session) {
db := session.DB("test") //数据库名称
collection := db.C("a") //如果该集合已经存在的话,则直接返回

//t := struct{ Url string }{}
//collection.Find(bson.M{}).One(&t)
//fmt.Println(t)
count,_ := collection.Find(nil).Count()
pagecount := count/100
t := struct{ Url string }{}
for i:=0;i<=pagecount;i++ {
query := collection.Find(bson.M{}).Skip(i*100).Limit(100).Batch(2).Iter()
for query.Next(&t) {
res1,err :=GetInfo("http://www.cndzys.com"+t.Url)
if err == nil {
db.C("b").Insert(bson.M{"title":res1["title"],"desc":res1["desc"]})
}
}
}

}


这样就可以正常采集数据.

以下是采集的接口

func GetInfo(url string) (map[string]string,error)  {
res,err := http.Get(url)
info := make(map[string]string)
if err !=nil {
fmt.Println("获取远程内容为空")
return info , errors.New("get url error")
}
body,err := ioutil.ReadAll(res.Body)
if err !=nil {
fmt.Println("解析错误")
return info , errors.New("get body error")
}
html := string(body)
regex1,err := regexp.Compile("<h1>(.*?)</h1>")
regex2,err := regexp.Compile("(?is)<div class=\"content_text\">(.*?)</div>")
des := regex2.FindAllStringSubmatch(html,-1)
titles := regex1.FindStringSubmatch(html)
if (len(titles) < 1) {
return info,errors.New("titles error get")
}
if (len(des) < 1) {
return info,errors.New("desc error get")
}
info["title"] = titles[1]
info["desc"] = des[0][0]

res.Body.Close()
return info,nil
}
...全文
210 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
ecshop528 2014-09-14
  • 打赏
  • 举报
回复
引用 5 楼 svenwang 的回复:
限制并发的方法我已经在#3里写了,用一个chan struct{}。我那个例子里设置的最大并发数是64 如果超出并发上限,则

limit <- struct{}{}
这行代码就会阻塞,直到其他goroutine执行完GetInfo的这行语句:

<-limit
谢谢大哥。你很牛。。果然如此。问题解决了。 现在采集起来。杠杠的
svenwang 2014-09-14
  • 打赏
  • 举报
回复
限制并发的方法我已经在#3里写了,用一个chan struct{}。我那个例子里设置的最大并发数是64 如果超出并发上限,则

limit <- struct{}{}
这行代码就会阻塞,直到其他goroutine执行完GetInfo的这行语句:

<-limit
ecshop528 2014-09-14
  • 打赏
  • 举报
回复
引用 2 楼 ecshop528 的回复:
老大。还是不行 提示这个错误。我打印err,我在GetInfo 函数里面打印 获取远程内容为空 Get http://www.cndzys.com/yinshi/yaoshan/7060.html: WSARecv tcp 192.168.1.101:21 45: The specified network name is no longer available. 获取远程内容为空 Get http://www.cndzys.com/yinshi/yaoshan/203711.html: dial tcp 183.61.19.169:80: An operation on a socket could not be performed because the system lacked suffi cient buffer space or because a queue was full.
老大。如何限制并发呢。有相关的参考代码吗。网上搜索了下。没有相关代码的参考示例。 我也是第一次遇到过这个问题。。。go语言的资料真是太少了。
svenwang 2014-09-14
  • 打赏
  • 举报
回复
现在这个错误是在http包里的了,和mgo没有关系。从错误信息看是缓存不足,限制一下并发数试试:

var limit = make(chan struct{}, 64)

func GetInfo(url string) (map[string]string,error)  {
	limit <- struct{}{}
	defer func() {
		<-limit
	}()
	...
}
ecshop528 2014-09-14
  • 打赏
  • 举报
回复
老大。还是不行 提示这个错误。我打印err,我在GetInfo 函数里面打印 获取远程内容为空 Get http://www.cndzys.com/yinshi/yaoshan/7060.html: WSARecv tcp 192.168.1.101:21 45: The specified network name is no longer available. 获取远程内容为空 Get http://www.cndzys.com/yinshi/yaoshan/203711.html: dial tcp 183.61.19.169:80: An operation on a socket could not be performed because the system lacked suffi cient buffer space or because a queue was full.
svenwang 2014-09-14
  • 打赏
  • 举报
回复
估计是session生命周期的问题,你用sync.WaitGroup做一下同步试试

func InsertInfo(info map[string]string, session *mgo.Session) {
	db := session.DB("test") //数据库名称
	collection := db.C("a")  //如果该集合已经存在的话,则直接返回

	//t := struct{ Url string }{}
	//collection.Find(bson.M{}).One(&t)
	//fmt.Println(t)
	count, _ := collection.Find(nil).Count()
	pagecount := count / 100
	t := struct{ Url string }{}

	var wg sync.WaitGroup
	for i := 0; i <= pagecount; i++ {
		query := collection.Find(bson.M{}).Skip(i * 100).Limit(100).Batch(2).Iter()
		for query.Next(&t) {
			wg.Add(1)
			go func(uri string) {
				InsertMongo(collection, uri)
				wg.Done()
			}(t.Url)
		}
	}
	wg.Wait()
}

2,190

社区成员

发帖
与我相关
我的任务
社区描述
go语言学习与交流版
社区管理员
  • go语言社区
  • Freeman Z
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧