多线程爬虫

python (1998) 2020-10-28 15:29:04

现在网络爬虫看起来是很简单,如果做爬虫就是这种想法是错误的。爬虫设计的东西有许多,无论是爬虫框架,爬虫软件,爬虫程序,爬虫策略,编写爬虫都是比较麻烦的,写好爬虫程序后,从网站抓取数据似乎易如反掌。当然,当你大量在网站上抓东西时,某网站限制了爬虫行为,事情很快就会变得非常棘手。

对于那些对大量爬取团队或者企业来说,需要仔细了解爬虫的策略方案

大型业务抓取和普通的网页爬取应用不一样的是,采集的量也完全不一样。

由于时间通常是限制因素,大量数据抓取要求你的爬虫要以很高的速度抓取网页但又不能拖累数据质量,这时候企业用户就可以启用多线程爬虫

什么是多线程?

多线程是指爬虫程序中有多个命令同时执行,在一个程序中可以同时运行多个不同的线程来执行不同的任务,简单来说就一个单线程下面创建多个线程同时执行命令完成采集。

多线程的好处:

可以提高采集速率。在多线程爬虫程序中,一个线程采集的量比较小,执行多线程就可以加大采集量,提供采集的速率。

多线程与单线程的区别:

多线程能同时执行命令提高采集效率,单线程就是一个一个命令执行,采集速率较慢

多线程爬虫源码:

        package main

        import (
            "net/url"
            "net/http"
            "bytes"
            "fmt"
            "io/ioutil"
        )

        // 代理服务器(产品官网 www.16yun.cn)
        const ProxyServer = "t.16yun.cn:31111"

        type ProxyAuth struct {
            Username string
            Password string
        }

        func (p ProxyAuth) ProxyClient() http.Client {

            var proxyURL *url.URL
            if p.Username != ""&& p.Password!="" {
                proxyURL, _ = url.Parse("http://" + p.Username + ":" + p.Password + "@" + ProxyServer)
            }else{
                proxyURL, _ = url.Parse("http://" + ProxyServer)
            }
            return http.Client{Transport: &http.Transport{Proxy:http.ProxyURL(proxyURL)}}
        }

        func main()  {


            targetURI := "https://httpbin.org/ip"


            // 初始化 proxy http client
            client := ProxyAuth{"username",  "password"}.ProxyClient()

            request, _ := http.NewRequest("GET", targetURI, bytes.NewBuffer([] byte(``)))

            // 设置Proxy-Tunnel
            // rand.Seed(time.Now().UnixNano())
            // tunnel := rand.Intn(10000)
            // request.Header.Set("Proxy-Tunnel", strconv.Itoa(tunnel) )

            response, err := client.Do(request)

            if err != nil {
                panic("failed to connect: " + err.Error())
            } else {
                bodyByte, err := ioutil.ReadAll(response.Body)
                if err != nil {
                    fmt.Println("读取 Body 时出错", err)
                    return
                }
                response.Body.Close()

                body := string(bodyByte)

                fmt.Println("Response Status:", response.Status)
                fmt.Println("Response Header:", response.Header)
                fmt.Println("Response Body:\n", body)
            }
        }

THE END

发表评论