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 ...
随机推荐
- iOS——plist的创建,数据写入与读取
iOS中plist的创建,数据写入与读取 Documents:应用将数据存储在Documents中,但基于NSuserDefaults的首选项设置除外Library:基于NSUserDefaults的 ...
- CMake版本升级
CMake 是一个可扩展的开源系统,以独立于编译器的方式在操作系统中管理生成过程.与许多跨平台系统不同,CMake 旨在与本机生成环境结合使用.放置在每个源目录中的简单配置文件(称为 CMakeLis ...
- Centos7下 升级php5.4到7.1 yum安装
1.查看当前 PHP 版本 php -v 查看当前 PHP 相关的安装包,删除之 yum list installed | grep php yum remove php yum remove php ...
- Odoo 13 released..
origin https://medium.com/@jc_57445/odoo-13-is-fantastic-f2b421696b49 Most striking changes The most ...
- kafka consumer 的配置(五)
fetch.min.bytes. #获取最小字节数据 Consumer 向broker中要数据时是按大小来返回的,如果数据没有达到指定的MB,consumer会处于等待状态,直到broker 从pro ...
- 转载:同一台电脑教你配置多个Tomcat的环境变量
装两个tomcat 分别是6.0和7.0 可想运行tomcat6.0 但是实际上却运行tomcat7.0 两个版本都是用解压缩包 其实就是不能运行tomcat6.0 只能运行7.0 两个环境变量都配置 ...
- 一个包含python和java环境的dockerfile
现在一个项目中遇到python调用java的jar包的环境.为了方便发布,编写了这个dockerfile,作为基础镜像. #this docker file is used to build runt ...
- Windows下mysql导出和导入数据库表(命令行)
导出: 1.打开ctrl+R输入cmd 打开命令行 2.cd D:\mysql-8.0.15-winx64\bin 到MySQL的bin目录 3.输入命令 mysqldump -u root -p ...
- swiper手滑动轮播图后自动轮播失效解决办法
设置autoplay:true之后,再设置 autoplay:{disableOnInteraction: false} --------------------------------------- ...
- 基于TCP 协议的socket 简单通信
DNS 服务器:域名解析 socket 套接字 : socket 是处于应用层与传输层之间的抽象层,也是一组操作起来非常简单的接口(接受数据),此接口接受数据之后,交由操作系统 为什么存在 soc ...