golang爬虫使用splash进行JS渲染服务

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

    golang爬虫使用splash进行JS渲染服务

    起因

    发现之前写的 shein 爬虫突然失效了。页面返回提示: Enable JavaScript and cookies to continue

    us.shein.com needs to review the security of your connection before proceeding.
    Ray ID: 78698c2b8b837cdd
    Performance & security by Cloudflare
    

    尝试更换代理IP, 请求头都没用。根据提示来看确实被反爬了。应该启用 JS渲染
    考虑到Go语言常用的 chromedp 浏览器爬虫效率较低。想起以前使用python的 scrapy 爬虫框架时结合 Splash 可做 JS渲染 服务挺好用的。想着 Splash 本身基于HTTP的API, 是跨语言的应该可以代替 chromedp 来做浏览器渲染。

    Splash运行环境

    使用 Docker (version >= 17), 安装 Splash 服务.

    # 下载 splash 镜像
    sudo docker pull scrapinghub/splash
    # 启动 splash 容器。因需要使用宿主机的HTTP代理服务。故添加 --net host 参数
    sudo docker run -it --net host -p 8050:8050 --rm scrapinghub/splash
    

    docker run 命令添加参数 --net host, 使容器能使用宿主机网络环境的HTTP代理服务。
    如此便开启了一个运行Splash应用的Docker容器该容器共享宿主机网络。
    访问地址: http://127.0.0.1:8050

    在Golang中使用

    发起一个 GET方法 的HTTP请求使用 splashJS渲染 服务。流程如下

    1. 爬虫程序通过 发起HTTP请求调用 splash 服务端的 API接口默认为本地8050端口。
    2. splash 模拟浏览器请求对请求结果进行 JS渲染得到网页完整的HTML代码。
    3. 爬虫程序通过 API接口 返回的结果得到 JS渲染 过后的HTML网页代码。

    使用 Splash 的API接口 的 execute (或 run)方法在 lua_source 参数中携带执行脚本参数。

    lua_source 参数示例:

    function main(splash)
        return 'hello'
    end
    

    通过curl命令调用API接口示例:

    # execute 方法
    curl 'http://127.0.0.1:8050/execute?lua_source=function+main%28splash%29%0D%0A++return+%27hello%27%0D%0Aend'
    

    Golang语言中请使用 net/url 包的 url.QueryEscape 方法对 lua_source 参数进行 urlEncode 转义。

    伪代码如下所示:

    import (
    	"fmt"
    	neturl "net/url"
    	"strconv"
    	"strings"
    	"time"
    	"github.com/gocolly/colly/v2"
    )
    
    func GetSplashUrl(url string) string {
    	luaSourceFmt := `splash:on_request(function(request)
    	request:set_proxy{"0.0.0.0",1079}
    	end)
    	splash:set_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36")
    	assert(splash:go("%s"))
    	return splash:html()
    	`
    	q := neturl.QueryEscape(fmt.Sprintf(luaSourceFmt, url))
    	return "http://127.0.0.1:8050/run?lua_source=" + q
    }
    
    func main(){
        reqUrl := GetSplash("https://www.example.com")
        // TODO 通过reqUrl发起HTTP请求返回结果已被Splash处理过为JS渲染过的HTML页面。
    }
    

    通过HTTP请求调用Splash的API接口

    1. http://localhost:8050/render.html
    2. http://localhost:8050/render.png
    3. http://localhost:8050/execute
    4. http://localhost:8050/run

    execute 方法接口的 lua_source 参数如下所示:

    function main(splash, args)
        assert(splash:go(args.url))
        assert(splash:wait(1.0))
        return splash:html()
    end
    

    run 方法接口的 lua_source 参数如下所示:

    assert(splash:go(args.url))
    assert(splash:wait(1.0))
    return splash:html()
    

    Splash操作脚本

    操作方法

    • splash:go 网页链接跳转. 目前只支持 GET 和 POST 请求。支持指定 HTTP 请求头表单等数据.
    • splash:set_user_agent(value) 设置UA请求头
    • splash:select HTML元素CSS选择器

    request 对象

    request 对象splash:on_request(callback) 方法的回调函数中调用

    • request:set_proxy{host, port, username=nil, password=nil, type='HTTP'} 设置请求代理
    • request:set_header(name, value) 设置请求头

    splash:on_request

    splash:on_request(callback) 设置一个回调函数用于在发起HTTP请求前操作 request 对象

    # 添加代理
    splash:on_request(function(request)
        request:set_proxy{
            host = "0.0.0.0",
            port = 8990,
            username = splash.args.username,
            password = splash.args.password,
        }
    end)
    

    https://splash.readthedocs.io/en/stable/scripting-tutorial.html
    https://splash.readthedocs.io/en/stable/scripting-ref.html#splash-on-request
    request 请求对象 https://splash.readthedocs.io/en/stable/scripting-request-object.html
    Splash安装和使用 https://blog.csdn.net/qq_53582111/article/details/121649717
    深入使用 Splash 服务 https://www.5axxw.com/wiki/content/hf16nn

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
    标签: go

    “golang爬虫使用splash进行JS渲染服务” 的相关文章