分析京东网站结构

浏览器调试分析

商品列表url分析

打开京东网站,随便输入一个关键字,点开抓包工具(ctrl+F)

 看到不是动态加载的是不是有点激动?但是你拿到的并不是全数据,为什么这么说呢,往下看

当滑动滚轮时,出现了新数据

 查看请求url及参数

 

尝试去掉不必要的参数,经过多次的尝试发现,要获取到数据只需要想它发送请求就可以拿到数据:

url:https://search.jd.com/s_new.php?keyword=电脑&page=1&s=30
# 注意page与s的关系,注意最大页码的值(商品页面显示页码为100,那么你在拼接url时,最大页码必须是100*2)
参数:   keyword:搜索的关键字   page:页码数   s:每一页的数据条数

但是,你会发现他只能拿到三十几条左右的数据,而正常是当滚轮滑动到底端时会有六十几条数据,这时候不要慌,因为你会发现当url的page=2&s=60时,就会出现,原来滚轮滑动到底部后获取的新数据

因此,当滚轮滑动到底部时,原来的1页,展示了两页的数据

既然明白了他们的数据请求方式,那么拿到所有的商品列表就很简单了

 拿到后发送请求获取到response,进行xpath解析就可以了

详情页评论分析  

上面我们已经获取了商品列表页需要的数据,记得拿详情页的url

接下来继续分析详情页数据接口的url:随便点击一个商品,抓包,全局搜索

 查看请求的url:

 分析url和参数:

将这里的请求url输入浏览器地址栏,看能否拿到数据:

 很明显,可以拿到数据,接着我们看携带的参数

url:https://club.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98&productId=100006581268&score=0&sortType=5&page=0&pageSize=10&isShadowSku=0&fold=1

 参数:
        callback: fetchJSON_comment98  # 这是个回调函数
        productId: 100006581268           # 商品id
        score: 0                             # 不知道啥东西
        sortType: 5                        # 不知道啥东西
        page: 0                             # 评论的页码 
        pageSize: 10                      # 每页显示几条数据 
        isShadowSku: 0        
        fold: 1

我们虽然拿到这些参数,但是,你会疑惑这些参数是不是通过js动态生成的?怎么获取这些参数呢?

其实:对于这种情况来说,先不要老是想着找它的来源,因为有时候就单纯的获取数据来说,有些参数并不是必须要携带的

 这里,我们尝试去掉一些不必要的参数

url:https://club.jd.com/comment/productPageComments.action?productId=100003383325&score=0&sortType=5&page=3&pageSize=10

参数:
    productId:商品id
    score:不知道啥东西,但这个必须带
    sortType:同上
    page:评论的页码
    pageSize:每页评论的条数

至此,我们的评论数据接口就搞定了

解决只能爬取70条左右的评论的问题

京东做了反扒机制,当你访问评率过快或者使用单个ip访问的时候只允许你拿70左右的数据,如何解决呢?

ip代理池+设置请求发送的间隔时间:以scrapy框架为例:

IP代理池(本人ip代理是从网上爬取的免费代理,存放在数据库中):

下载器中间件文件:

class AllJdDownloaderMiddleware:
    # Not all methods need to be defined. If a method is not defined,
    # scrapy acts as if the downloader middleware does not modify the
    # passed objects.
    conn = None
    cursor = None
    proxy_list = []

    def __init__(self):
        self.conn = pymysql.Connect(host=MYSQL_IPS_CONNECT['host'], user=MYSQL_IPS_CONNECT['user'],
                                    port=MYSQL_IPS_CONNECT['port'], password=MYSQL_IPS_CONNECT['password'],
                                    db=MYSQL_IPS_CONNECT['db_name'],
                                    charset='utf8')
        self.cursor = self.conn.cursor()
        sql = 'select ip,port,http_type from ips'
        try:
            self.cursor.execute(sql)
            # 取数据库中所有的ip
            all_ip = self.cursor.fetchall()
            if not all_ip:
                raise ValueError('您没有代理ip了!')
            for ips in all_ip:
                ip, port, http_type = ips
                self.proxy_list.append(f"{http_type.lower()}s://{ip}:{port}")
        except Exception as e:
            print(e)

    @classmethod
    def from_crawler(cls, crawler):
        # This method is used by Scrapy to create your spiders.
        s = cls()
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        return s

    def process_request(self, request, spider):
        request.meta['http_proxy'] = random.choice(self.proxy_list)
        request.cookie = COOKIE

        return None

    def process_response(self, request, response, spider):
        print(response['cookies'])
        if (spider.comment_url.split('?')[0] in request.url):
            if not response.text:
                # 如果评论页面数量数据取不到,换代理重新请求
                request.meta['http_proxy'] = random.choice(self.proxy_list)
                return request
        return response

    def process_exception(self, request, exception, spider):
        # 捕获到异常请求,换代理ip,重新发送请求
        request.meta['http_proxy'] = random.choice(self.proxy_list)
        return request

    def spider_opened(self, spider):
        spider.logger.info('Spider opened: %s' % spider.name)

设置请求发送间隔时间:

settings.py

DOWNLOAD_DELAY = 2 # 单位秒

然后你就可以开搞了。

本人此次项目获取的是每个商品的价格、好评、差评、好评度等数据 ,并未爬取评论,但数据接口是相同的,看一下运行结果

 总结一下分析的url:

商品列表url:
for page in range(1, 200):
    url = 'https://search.jd.com/s_new.php?keyword=%s&page=%d&s=%d' % ('电脑', page, page * 30)
参数:
    keyword:搜索关键字
    page:列表页码
    s:展示的商品数量
    
评论列表url:
for page in range(0,100)
    url = 'https://club.jd.com/comment/productPageComments.action?productId=%s&score=0&sortType=5&page=%d&pageSize=%d' % ('100003383325',page,10)
参数:
    productId=100003383325 # 商品id,其他参数不变
    score=0
    sortType=5
    page=0       # 评论页码数,
    pageSize=10  # 每页评论条数

完。。。。。。。。。。。。。

原文地址:https://www.cnblogs.com/kindvampire/p/12914102.html