go爬虫之爬取豆瓣电影
go爬取豆瓣电影
好久没使用go语言做个项目了,上午闲来无事花了点时间使用golang来爬取豆瓣top电影,这里我没有用colly框架而是自己设计简单流程。mark一下
思路
定义两个channel,一个channel存放web网页源内容,另一个存放提取后的有效内容。
多个goroutine并发爬取网页源内容放到存放web网页的channel里,再启动goroutine去存放web网页的channel里读取内容,读取到内容后启动goroutine去提取有效值存放到channel里,最后持久化写入本地文件(文件写操作并非线程安全所以这里我没有使用多goroutine)。
代码
具体代码如下,如果想执行看效果需要go get github.com/PuerkitoBio/goquery
安装三方包或者直接点这里拉取代码设置GOPATH之后便可运行
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"regexp"
"strings"
"time"
"os"
"github.com/PuerkitoBio/goquery"
)
/*
通过多个goroutine并发执行爬取操作,channel存放要爬取url内容和爬取结果
这样只需要设计爬取函数和提取函数
*/
func get_web_content(url string, chan_web chan string) {
resp, err := http.Get(url)
if err != nil {
fmt.Println("http get error", err)
return
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("read error", err)
return
}
chan_web <- string(body)
}
func extract_valid_content(body string, chan_r chan []byte) {
dom, err := goquery.NewDocumentFromReader(strings.NewReader(body))
if err != nil {
fmt.Println(err)
}
dom.Find("ol.grid_view div.item").Each(func(i int, selection *goquery.Selection) {
// extract result
result := make(map[string]string)
name := selection.Find("div.info span.title").First().Text()
doctor_str := selection.Find("div.info div.bd p").First().Text()
r := regexp.MustCompile(`导演:(?s:(.*?))(主演|主|&|\.\.\.)`)
doctor := r.FindAllStringSubmatch(doctor_str, -1)[0][1]
rating_num := selection.Find("div.star span.rating_num").First().Text()
evaluation_str := selection.Find("div.star span").Last().Text()
r = regexp.MustCompile(`(?s:(.*?))人评价`)
evaluation := r.FindAllStringSubmatch(evaluation_str, -1)[0][1]
ranking := selection.Find("div.pic em").First().Text()
result["name"] = name
result["doctor"] = doctor
result["rating_num"] = rating_num
result["evaluation"] = evaluation
result["ranking"] = ranking
json_str, err := json.Marshal(result)
if err != nil {
fmt.Println(err)
return
}
chan_r <- json_str
})
}
func main() {
var (
OutputFile = "./film_crawl.txt"
)
base_url := "https://movie.douban.com/top250?start=%d&filter="
chan_web_content := make(chan string)
defer close(chan_web_content)
chan_r := make(chan []byte)
defer close(chan_r)
for i := 0; i < 10; i++ {
url := fmt.Sprintf(base_url, i*25)
go get_web_content(url, chan_web_content)
}
go func() {
for {
web_content, ok := <- chan_web_content
if !ok {
break
}
go extract_valid_content(web_content, chan_r)
}
}()
flag := false
to := time.NewTimer(time.Second * 5)
file, err := os.OpenFile(OutputFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
if err != nil {
fmt.Println("Failed to open the file", err.Error())
return
}
defer file.Close()
for {
if flag {
break
}
to.Reset(time.Second * 5)
select {
case res := <- chan_r:
fmt.Printf("%s\n", res)
file.Write(res)
file.WriteString("\n")
case <- to.C:
flag = true
break
}
}
fmt.Println("end")
}
go爬虫之爬取豆瓣电影的更多相关文章
- 第一个nodejs爬虫:爬取豆瓣电影图片
第一个nodejs爬虫:爬取豆瓣电影图片存入本地: 首先在命令行下 npm install request cheerio express -save; 代码: var http = require( ...
- 一起学爬虫——通过爬取豆瓣电影top250学习requests库的使用
学习一门技术最快的方式是做项目,在做项目的过程中对相关的技术查漏补缺. 本文通过爬取豆瓣top250电影学习python requests的使用. 1.准备工作 在pycharm中安装request库 ...
- 爬虫——正则表达式爬取豆瓣电影TOP前250的中英文名
正则表达式爬取豆瓣电影TOP前250的中英文名 1.首先要实现网页的数据的爬取.新建test.py文件 test.py 1 import requests 2 3 def get_Html_text( ...
- 零基础爬虫----python爬取豆瓣电影top250的信息(转)
今天利用xpath写了一个小爬虫,比较适合一些爬虫新手来学习.话不多说,开始今天的正题,我会利用一个案例来介绍下xpath如何对网页进行解析的,以及如何对信息进行提取的. python环境:pytho ...
- 初识python 之 爬虫:爬取豆瓣电影最热评论
主要用到lxml的etree解析网页代码,xpath获取HTML标签. 代码如下: 1 #!/user/bin env python 2 # author:Simple-Sir 3 # time:20 ...
- scrapy爬虫框架教程(二)-- 爬取豆瓣电影TOP250
scrapy爬虫框架教程(二)-- 爬取豆瓣电影TOP250 前言 经过上一篇教程我们已经大致了解了Scrapy的基本情况,并写了一个简单的小demo.这次我会以爬取豆瓣电影TOP250为例进一步为大 ...
- Python开发爬虫之静态网页抓取篇:爬取“豆瓣电影 Top 250”电影数据
所谓静态页面是指纯粹的HTML格式的页面,这样的页面在浏览器中展示的内容都在HTML源码中. 目标:爬取豆瓣电影TOP250的所有电影名称,网址为:https://movie.douban.com/t ...
- 爬虫系列1:Requests+Xpath 爬取豆瓣电影TOP
爬虫1:Requests+Xpath 爬取豆瓣电影TOP [抓取]:参考前文 爬虫系列1:https://www.cnblogs.com/yizhiamumu/p/9451093.html [分页]: ...
- 爬虫系列(十) 用requests和xpath爬取豆瓣电影
这篇文章我们将使用 requests 和 xpath 爬取豆瓣电影 Top250,下面先贴上最终的效果图: 1.网页分析 (1)分析 URL 规律 我们首先使用 Chrome 浏览器打开 豆瓣电影 T ...
随机推荐
- delphi中Treeview的使用介绍
今天重点学习了TreeView的使用方法,基本的已经写了,现在主要想说的是如何显示数据库的资料,今天只是做了个较简单的例子,一个父节点下显示数据库中某个field的值.代码如下: procedure ...
- 神经网络(NN)实现多分类-----Keras实现
IRIS数据集介绍 IRIS数据集(鸢尾花数据集),是一个经典的机器学习数据集,适合作为多分类问题的测试数据,它的下载地址为:http://archive.ics.uci.edu/ml/machi ...
- nginx 配置 https 并强制跳转(lnmp一键安装包)
目录 一.安装包 二.配置 三.查看配置文件 3.1.设定强制跳转 https 3.2 Rewrite 常用全局变量举例 一.安装包 安装大家按照官方说的安装即可. ./install.sh lnmp ...
- 《精通并发与Netty》学习笔记(11 - 详解NIO (二) 分散/聚集 Scatter/Gather、Selector)
一.分散/聚集 Scatter/Gather scatter/gather指的在多个缓冲区上实现一个简单的I/O操作,比如从通道中读取数据到多个缓冲区,或从多个缓冲区中写入数据到通道:scatter( ...
- 最新 房多多java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.房多多等10家互联网公司的校招Offer,因为某些自身原因最终选择了房多多.6.7月主要是做系统复习.项目复盘.LeetCo ...
- 在java web 工程中实现登录和安全验证
登录验证代码 package security; import java.io.IOException; import javax.servlet.ServletException; import j ...
- K8s架构详解
每个微服务通过 Docker 进行发布,随着业务的发展,系统中遍布着各种各样的容器.于是,容器的资源调度,部署运行,扩容缩容就是我们要面临的问题. 基于 Kubernetes 作为容器集群的管理平台被 ...
- 关于element中的父子组件的传值问题
首先讲一下父子组件的传值问题. 这是大家很熟悉的一张图,讲述了父子组件传值的过程.父组件通过prop传值给子组件,子组件通过$emit给父组件发送消息来使父组件的prop发生变化.这都是老生常谈了.下 ...
- thinkphp5相关
THINKPHP5代码风格规范(基于PSR): https://www.jianshu.com/p/e53d26407e68
- [转帖]Intel 上一代 可扩展CPU的简单报价
8.1万元人间毒物!Intel 28核铂金版Xeon 8180零售上市 http://news.mydrivers.com/1/541/541670.htm 猜你想看:英特尔 CPU处理器 Xeon ...