亚马逊listing爬虫(排行 星级 评论数)

背景介绍

  1. 公司在各电商平台(亚马逊/沃尔玛/Ebay/京东国际/速卖通)有大量商品,但是没有一个能聚合各商品的排行的工具或功能。现需开发一个每月统计商品排行的功能,供公司数据决策做参考。
  2. 对上述5个平台了解后发现只有亚马逊有提供精准排行数据,其他平台如必须则只能通过在指定商品分类的列表页去搜索该商品 才能得知排行,商量后觉得这种方式不可取,所以暂时只抓取亚马逊的排行数据,星级/评论数为附带抓取数据。

方案选择

F12查看内容发现数据是绑定到dom上的 没有直接的ajax数据接口可用(一般有直接的数据接口优选接口),所以只能取dom解析得到数据。

得到dom可用通过以下方案 (https://站点host/dp/asin)

  • 方案一 jsoup(解释1)直接访问listing页面
    优点:只访问单页 不加载静态资源(js/css/img…) 给代理省流量;速度快
    缺点:如果对方服务器通过静态资源做页面事件监听并以此为风控鉴定(解释2),则很快会被限流或直接禁止访问
  • 方案二 selenium(解释3)访问listing页面,并将dom转换为jsoup的dom(jsoup对dom解析的api更好用),然后解析数据

    优点:基本可以直接忽略接口加密、页面行为上传的导致的风控

    缺点:速度慢;打开一个链接附带的所有静态资源都会占用代理带宽

出现的问题及解决方案

问题一 验证码

先方案一在本地运行

  • 一段时间后发现dom里没有相关数据了,debug发现http403直接跳转到了验证码页面,好在验证码都是比较简单的;jsoup不能直接操作dom,要破解验证码+发送验证码接口,这样比较麻烦,为了省时,直接使用方案二,将识别好的验证码通过webdriver发送过去。

解决方案

  • 切换方案二
  • 使用python的easyocr+flask 搭建了一个验证码识别服务;easyocr在linux下安装可能有点麻烦 按教程多试几次。easyocr验证码识别率做不到100%,但是整体还是可以接受的。
# coding=utf-8
import base64
import urllib
import uuid

from flask import Flask
from flask import request, json
import easyocr
import os

app = Flask(__name__)
reader = easyocr.Reader(['ch_sim', 'en'], gpu=False)

# 接口的入参是验证码图片的url
@app.route('/ocrUrl', methods=['POST'])
def ocrCaptchaUrl():
    try:
        data = request.get_data()
        print(data)
        json_data = json.loads(data.decode("UTF-8"), strict=False)
        allow = json_data.get("allow")
        url = json_data.get("url")

        rsp = urllib.request.urlopen(url)
        file_name = str(uuid.uuid1()) + ".jpg"
        file = open(file_name, "wb")
        file.write(rsp.read())
        file.close()
        res = reader.readtext(file_name, detail=0, allowlist=allow)
        os.remove(file_name)
        return '{"status":"200", "result":"' + res[0] + '"}'
    except Exception as e:
        print(e)
        return '{"status":"500"}'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8181)

问题二 代理带宽不够

linux下运行一段时间后 日志经常报错浏览器超时崩溃,经排查发现是代理带宽不够用,因为selenium加载一个链接时会加载附带的所有静态资源,对代理带宽消耗大。

解决方案

  • 修改chromeDriver配置 不加载img/css等资源
// 禁用图片 & 样式 & flash
Map<String, Object> prefs = new HashMap<>();
prefs.put("profile.managed_default_content_settings.images", 2);
prefs.put("profile.managed_default_content_settings.stylesheet", 2);
prefs.put("dom.ipc.plugins.enabled.libflashplayer.so", "false");
chromeOptions.setExperimentalOption("prefs", prefs);
  • linux服务器配置比本地机器高,访问速度快,控制selenium访问速度,单条记录最少3200毫秒

问题三 防止过快被服务器标记

一直在抓取,容易被标记ip导致长时间不能访问,这点是防范于未然。

解决方案

  • 程序每开启一个chrome,都随机配置一个UserAgent,爬取n条记录后销毁chrome 下次需要再重新生成。
  • 线程id和chrome绑定,控制并发 最多使用N(线程个数)个chrome实例。
  • 代理和非代理轮番使用。因为代理资源不够,所以使用代理时效率低,但是又不能完全使用服务器ip去抓取,所以这里轮番去使用,且定时任务执行了10次后休息一段时间

问题四

其他业务细节问题以及平时粗心容易犯的错误就不记录了

解释

解释1jsoup 爬虫工具库,主要包含http的请求操作、Dom解析操作。提供的dom api操作起来和jQuery一样非常方便

解释2页面风控 部分大厂的产品会过度收集用户信息,包括用户设备信息、在页面的操作轨迹,以此对用户进行分析,并将分析结果作为风控或用户画像的分析,字节系/阿里系产品都有这类骚操作。web端的收集一般会把数据当成参数放在一个静态资源的请求链接上(如xx.gif?data=xxx) 其中xx.gif并不是一个实际的图片 而是服务器收集数据的一个接口

解释2selenium
自动化测试工具包,提供了程序控制浏览器行为的api;liunx下需安装对应浏览器服务 可headless模式运行;

总结

需求虽然挺简单,但是从代码完成 到问题修补 最后到数据抓取完成陆续花了不少时间,其中不少问题是细心一点可以避免的。总结下次做事细心点~

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值