go语言 grequests+goquery 简单爬虫,使用多协程并发爬取

/*下载工具*/
package main

import (
	"fmt"
	//go语言版本的jquery
	"github.com/PuerkitoBio/goquery"
	"os"
	"sync"
	"strings"
	//go语言版本的request
	"github.com/levigross/grequests"
	"time"
	"strconv"
)

var wg sync.WaitGroup

func main() {
	now := time.Now()
	initalUrls := []string{"http://www.zngirls.com/girl/18071/album/", }
	for _, url := range initalUrls {
		doc, err := goquery.NewDocument(url)
		if err != nil {
			fmt.Errorf("下载错误:%#v", err)
			os.Exit(-1)
		}

		doc.Find(".igalleryli_link").Each(func(i int, s *goquery.Selection) {
			src, exists := s.Find("img").Attr("src")
			fmt.Printf("开始下载影集图片:%v\n", src)
			if (exists) {
				wg.Add(1)
				go func(src string) {
					defer wg.Done()

					//下载图片
					//tryTimes := map[int]int
					n := 0
					s := strings.Replace(src, "cover/", "", 1)
					ss := strings.Split(s, "/")
					fm := strings.Join(ss[:len(ss) - 1], "/")
					sf0 := fm + "/%d.jpg"
					sfn := fm + "/%03d.jpg"

					for {
						//持续下载
						s := ""
						if n == 0 {
							s = fmt.Sprintf(sf0, n)
						} else {
							s = fmt.Sprintf(sfn, n)
						}

						fmt.Printf("准备下载: %v\n", s)
						res, _ := grequests.Get(s, &grequests.RequestOptions{
							//结构体可以对指定的类型给值,而不一定都赋值
							Headers:map[string]string{
								"Referer":"http://www.zngirls.com",
								"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"}})
						//条件需要修改,如果没有图片,返回的是盗链,图片4kb
						if res.StatusCode != 200 {
							fmt.Printf("下载失败,退出影集下载:%s\n", src)
							break
						}

						//图片可能是该网站,返回的盗链图片(4kb左右)
						length := res.Header.Get("Content-Length")
						slen,_ := strconv.Atoi(length)
						if slen < 4100{
							fmt.Printf("下载内容失败,退出影集下载:%s\n", src)
							break
						}

						index := strings.Index(s, "gallery")
						if index == -1 {
							fmt.Errorf("无效地址,找不到gallery关键词,解析失败:%s\n", src)
							return
						}

						ss2 := strings.Split(string(s[index:]), "/")
						dirname := strings.Join(ss2[:len(ss2) - 1], "/")
						if _, err := os.Stat(dirname); err != nil {
							fmt.Printf("创建下载文件夹:%s\n", dirname)
							os.MkdirAll(dirname, 0666)
						}

						filename := strings.Join(ss2, "/")
						res.DownloadToFile(filename)
						fmt.Printf("成功下载图片到:%s\n", filename)
						n++
					}
				}(src)
			}
		})
	}

	wg.Wait()
	//4M的带宽下载,需要16m36s,总大小202M,10个文件夹,560个文件
	fmt.Printf("下载任务完成,耗时:%#v\n", time.Now().Sub(now))
}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于Python 3的多协程以及队列爬取时光网电视剧top100的示例代码: ```python import requests from bs4 import BeautifulSoup import asyncio import aiohttp import time from queue import Queue async def fetch(session, url): async with session.get(url) as response: return await response.text() async def parse(html): soup = BeautifulSoup(html, 'html.parser') for item in soup.select('div[class="mov_con"] ul li'): rank = item.find('span', class_='top_num').text name = item.find('span', class_='mov_title').text score = item.find('span', class_='total_score').text print(rank, name, score) async def worker(session, queue): while not queue.empty(): url = queue.get() html = await fetch(session, url) await parse(html) async def main(): urls = [f'http://www.mtime.com/top/tv/top100/index-{i+1}.html' for i in range(10)] queue = Queue() for url in urls: queue.put(url) async with aiohttp.ClientSession() as session: tasks = [asyncio.create_task(worker(session, queue)) for _ in range(10)] await asyncio.gather(*tasks) if __name__ == '__main__': start_time = time.time() asyncio.run(main()) end_time = time.time() print(f'Time used: {end_time - start_time} seconds') ``` 这段代码使用了Python的asyncio库和aiohttp库来实现多协程异步爬取网页,使用了Python的queue模块来实现任务队列。首先,我们定义了`fetch`函数来异步获取网页内容,其返回值为响应的文本内容。然后,我们定义了`parse`函数来解析网页内容,提取出电视剧的排名、名称和评分,并输出到控制台。接着,我们定义了`worker`函数来作为协程的工作函数,从任务队列中取出一个URL并异步地解析该URL对应的网页。最后,我们定义了`main`函数来创建任务队列,创建异步协程,以及启动异步任务。在`main`函数中,我们先创建了10个URL,然后将这些URL放入任务队列中。接着,我们使用`async with`语句创建一个异步会话,并使用`create_task`函数创建10个异步协程,每个协程都调用`worker`函数,从任务队列中取出一个URL,并异步地解析对应的网页。最后,我们使用`asyncio.gather`函数等待所有的异步协程执行完毕。在程序执行结束后,我们还输出了程序的执行时间。 需要注意的是,由于时光网在一定时间内会对IP进行限制,如果爬虫速度过快可能会被封禁IP,因此我们在程序中设置了一个1秒钟的延时,以避免被封禁。如果您需要更高的爬取速度,请自行调整代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值