Go秒爬博客园100页新闻

利用go语言的协程并发优势爬取网页速度相当之快,博客园100页新闻标题只需一秒即可全部爬取

package main

import (
 "bytes"
 "fmt"
 "github.com/PuerkitoBio/goquery"
 "log"
 "net/http"
 "runtime"
 "strconv"
 "sync"
)

func Scraper(page string) string {
 // Request the HTML page.
 ScrapeURL := "https://news.cnblogs.com/n/page/" + page
 client := &http.Client{}
 reqest, _ := http.NewRequest("GET", ScrapeURL, nil)
 reqest.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
 reqest.Header.Set("Accept-Charset", "GBK,utf-8;q=0.7,*;q=0.3")
 //reqest.Header.Set("Accept-Encoding", "gzip,deflate,sdch")
 reqest.Header.Set("Accept-Language", "zh-CN,zh;q=0.8")
 reqest.Header.Set("Cache-Control", "max-age=0")
 reqest.Header.Set("Connection", "keep-alive")
 reqest.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36")
 res, err := client.Do(reqest)
 if err != nil {
  log.Fatal(err)
 }
 defer res.Body.Close()
 if res.StatusCode != 200 {
  log.Fatalf("status code error: %d %s", res.StatusCode, res.Status)
 }

 // Load the HTML document
 doc, err := goquery.NewDocumentFromReader(res.Body)
 if err != nil {
  log.Fatal(err)
 }

 // Find the review items
 var buffer bytes.Buffer
 buffer.WriteString("**********Scraped page " + page + "**********\n")
 doc.Find(".content .news_entry").Each(func(i int, s *goquery.Selection) {
  // For each item found, get the band and title
  title := s.Find("a").Text()
  url, _ := s.Find("a").Attr("href")
  buffer.WriteString("Review " + strconv.Itoa(i) + ": " + title + "\nhttps://news.cnblogs.com" + url + "\n")
 })
 return buffer.String()
}

func main() {
 runtime.GOMAXPROCS(runtime.NumCPU())
 ch := make(chan string, 100)
 wg := &sync.WaitGroup{}
 var page string
 for i := 1; i < 101; i++ {
  wg.Add(1)
  go func(i int) {
   page = strconv.Itoa(i)
   fmt.Printf("Scraping page %s...\n", page)
   ch <- Scraper(page)
   wg.Done()
  }(i)
 }
 wg.Wait()

 //print result
 for i := 0; i < 101; i++ {
  fmt.Println(<-ch)
 }
}

总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。如果你想了解更多相关内容请查看下面相关链接

(0)

相关推荐

  • golang利用不到20行代码实现路由调度详解

    前言 本文主要介绍了关于golang实现路由调度的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 项目地址 github (本地下载) 本项目依赖 使用标准库实现,无额外依赖 为什么需要路由调度层 golang http标准库只能精确匹配请求的URI,然后执行handler.现在一般web项目都至少有个Controller层,以struct实现,根据不同的请求路径派发到不同的方法中去. 路由调度器定义 由于golang暂时还不可以动态创建对象(比如java的Class.

  • Golang如何交叉编译各个平台的二进制文件详解

    Golang交叉编译平台的二进制文件 熟悉golang的人都知道,golang交叉编译很简单的,只要设置几个环境变量就可以了 # mac上编译linux和windows二进制 CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build # linux上编译mac和windows二进制 CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go

  • golang中命令行库cobra的使用方法示例

    简介 Cobra既是一个用来创建强大的现代CLI命令行的golang库,也是一个生成程序应用和命令行文件的程序.下面是Cobra使用的一个演示: Cobra提供的功能 简易的子命令行模式,如 app server, app fetch等等 完全兼容posix命令行模式 嵌套子命令subcommand 支持全局,局部,串联flags 使用Cobra很容易的生成应用程序和命令,使用cobra create appname和cobra add cmdname 如果命令输入错误,将提供智能建议,如 ap

  • 详解如何热重启golang服务器

    服务端代码经常需要升级,对于线上系统的升级常用的做法是,通过前端的负载均衡(如nginx)来保证升级时至少有一个服务可用,依次(灰度)升级. 而另一种更方便的方法是在应用上做热重启,直接升级应用而不停服务. 原理 热重启的原理非常简单,但是涉及到一些系统调用以及父子进程之间文件句柄的传递等等细节比较多. 处理过程分为以下几个步骤: 监听信号(USR2) 收到信号时fork子进程(使用相同的启动命令),将服务监听的socket文件描述符传递给子进程 子进程监听父进程的socket,这个时候父进程和

  • golang设置http response响应头与填坑记录

    1. 设置WriteHeader的顺序问题 之前遇到个问题,在一段代码中这样设置WriteHeader,最后在header中取Name时怎么也取不到. w.WriteHeader(201) w.Header().Set("Name", "my name is smallsoup") 用 golang 写 http server 时,可以很方便可通过 w.Header.Set(k, v) 来设置 http response 中 header 的内容.但是需要特别注意的

  • 详解Golang实现http重定向https的方式

    以前写代码时,都是直接将程序绑定到唯一端口提供http/https服务,在外层通过反向代理(nginx/caddy)来实现http和https的切换.随着上线后的服务越来越多,有一些服务无法直接通过反向代理来提供这种重定向,只能依靠代码自己实现.所以简要记录一下如何在代码中实现http到https的重定向. 分析 无论是反向代理还是代码自己实现,问题的本质都是判断请求是否是https请求. 如果是则直接处理,如果不是,则修改请求中的url地址,同时返回客户端一个重定向状态码(301/302/30

  • Golang中定时器的陷阱详解

    前言 在业务中,我们经常需要基于定时任务来触发来实现各种功能.比如TTL会话管理.锁.定时任务(闹钟)或更复杂的状态切换等等.百纳网主要给大家介绍了关于Golang定时器陷阱的相关内容,所谓陷阱,就是它不是你认为的那样,这种认知误差可能让你的软件留下隐藏Bug.刚好Timer就有3个陷阱,我们会讲 1)Reset的陷阱和 2)通道的陷阱, 3)Stop的陷阱与Reset的陷阱类似,自己探索吧. 下面话不多说了,来一起看看详细的介绍吧 Reset的陷阱在哪 Timer.Reset()函数的返回值是

  • Go语言的http/2服务器功能及客户端使用

    前言 大家都知道,Go的标准库HTTP服务器默认支持HTTP/2.那么,在这篇文章中,我们将首先展示Go的http/2服务器功能,并解释如何将它们作为客户端使用. 在这篇文章中,我们将首先展示Go的http/2服务器功能,并解释如何将它们作为客户端使用.Go的标准库HTTP服务器默认支持HTTP/2. 下面话不多说了,来一起看看详细的介绍吧 HTTP/2 服务器 首先,让我们在Go中创建一个http/2服务器!根据http/2文档,所有东西都是为我们自动配置的,我们甚至不需要导入Go的标准库ht

  • Go秒爬博客园100页新闻

    利用go语言的协程并发优势爬取网页速度相当之快,博客园100页新闻标题只需一秒即可全部爬取 package main import ( "bytes" "fmt" "github.com/PuerkitoBio/goquery" "log" "net/http" "runtime" "strconv" "sync" ) func Scraper(p

  • 利用正则表达式抓取博客园列表数据

    鉴于我在要完成的asp.net MVC 3 仿照博客园企业系统要用到测试数据,我自己输入太累,所以我就抓取了博客园的部分列表数据,还请dudu不要见怪. 在抓取博客园数据的时候采用了正则表达式,所以有不熟悉正则表达式的朋友可以参考相关资料,其实很容易掌握,就是在具体的实例中会花些时间. 现在我就来把我抓取博客园数据的过程叙述一下,如果有朋友有更好的意见,欢迎提出来. 要使用正则表达式抓取数据,首先就要创建一个正则表达式进行匹配,我推荐使用regulator,这个正则表达式工具,我们可以先使用这个

  • 详解Python爬虫爬取博客园问题列表所有的问题

    一.准备工作 首先,本文使用的技术为 python+requests+bs4,没有了解过可以先去了解一下. 我们的需求是将博客园问题列表中的所有问题的题目爬取下来. 二.分析: 首先博客园问题列表页面右键点击检查 通过Element查找问题所对应的属性或标签 可以发现在div class ="one_entity"中存在页面中分别对应每一个问题 接着div class ="news_item"中h2标签下是我们想要拿到的数据 三.代码实现 首先导入requests和

  • Python 批量刷博客园访问量脚本过程解析

    今早无聊...7点起来突然想写个刷访问量的..那就动手吧 仅供测试,不建议刷访问量哦~~ 很简单的思路,第一步提取代理ip,第二步模拟访问. 提取HTTP代理IP 网上很多收费的代理和免费的代理IP 如: 无论哪个网站,我们需要的就是爬取上面的ip和端口号,整理到一起. 具体的网站根据具体的结构爬取 比如上面那个网站,ip和端口在td标签 这里利用bs4爬取即可.贴上脚本 ##获取代理ip def Get_proxy_ip(): print("==========批量提取ip刷博客园访问量 By

  • python3实现暴力穷举博客园密码

    我之前想写路由器的密码暴力破解器,我手上只有极路由,发现极路由有安全限制,只能允许连续10密码错误,所以我改拿博客园练手. 博客园的博客有个功能是给博文设置一个密码,输入正确的密码才能看到文章的内容.经过测试发现这个密码验证功能,既没有验证码也没有提交频率的限制, 要写这个针对博客园的密码暴力破解器模型会非常简单,很好实现. 比如打开这个博文,会显示一个密码输入框:http://www.cnblogs.com/post/readauth?url=/muer/archive/2011/11/27/

  • 用ajax自动加载blogjava和博客园的rss

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>this is test</title> <sc

  • Python如何基于selenium实现自动登录博客园

    这篇文章主要介绍了Python如何基于selenium实现自动登录博客园,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 需要做的准备: 本文章是使用Chrome,所以需要Chormedriver.exe,具体的下载过程可以百度查到 Selenium是一种自动化测试工具,能模拟浏览器的行为,所以今天我就模拟一下浏览器登陆博客园的行为. 首先,分析问题,登陆博客园需要做些什么: 1.打开浏览器 2.输入博客园主页的网址 3.点击登陆按钮,等待页面跳

  • 在博客园博文中添加自定义右键菜单的方法详解

    页面设计 首先将这三个功能以一个列表<ul>的形式放置.鼠标移入时样式改变,移出时还原 <style> body{margin: 0;} ul{ margin: 0; padding: 0; list-style: none; } .list{ width: 100px; text-align: center; cursor: pointer; font:20px/40px '宋体'; background-color: #eee; } .in:hover{ background-

  • 打造博客园(cnblogs)超级自定义界面

    定制博客界面的核心方法是通过引用我们自己上传的外部JS,使外部JS的代码能在当前博客页面上执行,从而用这个JS修改页面DOM结构(加入新的界面元素,加入引用自定义的CSS,加入新的界面交互功能),然后我们就可以在自己写的这个外部JS里任意发挥了. 在博客园中的博客页面中引用外部JS的方法: 进入博客设置页面->设置->子标题,在这里,你可以输入你博客的一些子标题的内容,同时,你其实还可以输入如下html:<script src="XXXX">XXXX代表你的JS

  • 将博客园(cnblogs.com)数据导入到wordpress的代码

    我将这个分享出来,如果以后有谁需要可以直接下载下面插件 使用方法: 在cnblogs选择备份数据,导出一个XML到本地: 下载附件中的插件,安装至\wp-content\plugins目录: 后台开启插件后,可以在"工具"中找到"Cnblogs数据转换",进入: 选择刚才下载的XML文件,上传后系统会自动将数据转换并导入到wordpress中 备注: 这个插件只是单纯将博客园日志.随笔.文章导入到wordpress中,不会导入评论相册数据,因为cnblogs不提供这

随机推荐