(一)项目目标

1. 获取天猫店铺 “探路者官方旗舰店” 所有商品的名称、价格以及销量。

说明:本次项目目标是从一个热门店铺排行榜中随机选择的,没有任何针对性的含义。

该排行榜的网址为: http://www.xlphb.cn/index.php?c=shop

2. 该店铺的截图如下:

3. 左上角有一个 “所有商品” 的链接,点击进入如下截图:

4. 下方截图可以看到数据仍然是分页排列的,一共有14页的数据。

(二)网页分析

1. 首先还是打开charles,刷新页面,通过charles的搜索功能,找到目标数据的请求

2. 确认该请求是否全部包含目标数据

从下方截图可以看到,返回的数据格式是html,经手动确认,该请求包含该页的所有商品信息。

3. 分析请求的具体情况

从下方截图可以看到,该请求的具体信息是:

url: https://toread.tmall.com/i/asynSearch.htm?_ksTS=1529821691770_124&callback=jsonp125&mid=w-18307703560-0&wid=18307703560&path=/search.htm&search=y&spm=a1z10.3-b-s.w4011-18307703560.430.4ee0605f0KyPWs&scene=taobao_shop&pageNo=3&tsearch=y

请求类型: GET

4. 可以看到,这个请求有非常多的query参数。

经手动测试,有一些参数即使没有,也可以拿到数据,最终精简到如下url:

https://toread.tmall.com/i/asynSearch.htm?mid=w-18307703560-0&pageNo=2

注意,最后一个pageNo是指的页数,这样我们就可以直接通过改变pageNo,就能获得到不同页面的数据了。

5. 然后就是对页面数据进行解析时有一个坑。

一般来讲,我比较擅长使用css和正则表达式语法来选择数据,但是请看以下截图:

目标数据就在这些div和dl里面,但是淘宝设置的class 使用了这样的形式 "\"item" \", 这样我在用pyquery解析的时候总是要么要错,要么拿到数据。

但是没关系,下面的代码中,我使用了xpath语法来选择,躲开这个坑。

6. 网页基本分析完毕,请求只有一个,比较简单。但是要注意一下两点:

- 不知道淘宝的具体规则是什么,发送一个上面的请求并不一定能够获取到目标数据,但是只要重复不断发送,就能获取到。

- headers一定要写全。

(三)核心代码实现

1. 一些需要使用的模块和常量

import requests
from requests.exceptions import RequestException
from scrapy.selector import Selector
import csv
import random
from requests.exceptions import ConnectionErrors = requests.session()# csv结果文件的存储文件名
filename = '爬取结果.csv'# 定义代理池url,可以从代理池项目文件中找到接口
PROXY_POOL_URL = 'http://127.0.0.1:5555/random'

2. 随机切换User-Agent:

我是在项目中加入了一个agent.txt文件,里面存储了一些User-Agent可供使用。

# ag作为开关,仅第一次读取,之后就从ag里面拿
ag = None
def change_agent():global agif not ag:with open('agent.txt') as f:ag = f.readlines()return ag[random.randint(1,866)].strip()

3. 使用代理池

代理池的代码就不贴出来了,我是从github找的其他大神写的,从公开渠道获取免费代理后存储入redis的一个项目。

下面的代码使用前,我已经打开了redis和代理池的代码。

# 定义获取代理的函数
def get_proxy():"""从代理池中取出一个代理"""try:response = requests.get(PROXY_POOL_URL)if response.status_code == 200:return response.textreturn Noneexcept ConnectionError:return Nonedef build_proxy():"""将代理池中取出的代理构造成完整形式"""proxy = get_proxy()if proxy:return {'http': 'http://' + proxy,#'https': 'https://' + proxy}else:return None

4. 上面网页分析的部分有说到,发送该请求并不一定会获取到目标数据,如果没有获取到,需要重新发送。

这里定义个一个辅助函数,用于判断获取到的网页是否包含目标数据。

注意这里用的scrapy库里面的Selector模块,方便使用xpath语法选取数据。

当然还有其他库可以使用xpath语法,我对scrapy比较熟悉,所以使用这个。

def decide_if_loop(html):"""通过解析要拿到的页面第一个数据,判断是否拿到真正的页面,如果假的页面,就返回False"""selector = Selector(text=html)data = selector.xpath('/html/body/div/div[3]/div[1]/dl[1]/dd[2]/a/text()').extract_first()return False if not data else selector

5. 下面是获取页面的函数:

注意该函数内,调用了上面的切换User-Agent 和 使用代理池的函数。

def get_page(url):"""1. user-agent 不断切换2. 直接使用代理池中的代理来请求"""headers = {'User-Agent':change_agent(),'Referer':'https://toread.tmall.com','accept':'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01','x-requested-with':'XMLHttpRequest','accept-encoding':'gzip, deflate, br','accept-language':'zh-CN,zh;q=0.9,en;q=0.8'}try:response = s.get(url, headers=headers, verify = False, proxies=build_proxy())except:response = s.get(url, headers=headers, verify = False)if response.status_code == 200:return response.textelse:print("请求错误:{}".format(response.status_code))

6. 获取到真实页面之后,就需要进行页面解析

注意传入的参数是selector,就是前面的判断是否需要循环的函数中的返回值。

因为该函数内已经对页面进行解析后得到selector了,所以这里就不再重复,直接传入使用。

def parse_detail(selector):"""从拿到的真实页面中,解析出商品名,销量和价格"""data = []# 两个for循环解析一个html页面for i in range(1,13):for j in range(1, 6):title = selector.xpath('/html/body/div/div[3]/div['+str(i)+']/dl['+str(j)+']/dd[2]/a/text()').extract_first()price = selector.xpath('/html/body/div/div[3]/div['+str(i)+']/dl['+str(j)+']/dd[2]/div/div[1]/span[2]/text()').extract_first()num = selector.xpath('/html/body/div/div[3]/div['+str(i)+']/dl['+str(j)+']/dd[2]/div/div[3]/span/text()').extract_first()# 这个判断用于防止最后一页商品不全时,或者页面出现任何错误,值可能为空的情况if title and price and num:data.append([title.strip(), price.strip(), num.strip()])return data

7. 下面定义了两个函数,将解析到的数据存储本地csv文件。

def save_to_csv(rows, filename):if rows:with open(filename, "a") as f:f_csv = csv.writer(f)for row in rows:f_csv.writerow(row)    def write_csv_headers(filename):csv_headers = ["商品名称", "价格", "销量"]with open(filename, "a") as f:f_csv = csv.writer(f)f_csv.writerow(csv_headers)  

8. 下面的一些函数将整个代码串在一起

def loop(url):html = get_page(url)selector = decide_if_loop(html)if not selector:loop(url)else:data = parse_detail(selector)save_to_csv(data, filename)def get_urls():urls = []base_url = 'https://toread.tmall.com/i/asynSearch.htm?mid=w-18307703560-0&pageNo='for i in range(1, 15):urls.append(base_url + str(i))return urlsdef main():write_csv_headers(filename)for url in get_urls():loop(url)if __name__=="__main__":main()

(四)项目结果以及经验教训

经过不断的失败后重试,项目终于成功的获取了所有的14页的数据,共700多条,也就是该天猫店铺所有商品的名称、价格以及销量。展示截图如下:

经验教训:

淘宝的坑还是比较多的,在尝试的过程中:

1. 如果直接请求页面的url,可以直接获得到数据,但是全部是假数据;

2. 真实的请求也需要多次获取才能拿到目标数据;

3. 如果不使用代理池,自己的ip很容易被封掉。

4. 项目代码重用率比较低,如果要爬其他店铺的商品信息,如要重新进行分析。

本文仅供学习交流使用,请勿将其用于违法目的。

python爬虫--获取天猫店铺商品价格及销量相关推荐

  1. python爬虫获取天猫店铺信息(更新到2020年)

    python爬虫获取天猫店铺信息 爬取需求 在天猫搜索一个关键词,然后抓取这个关键词下的相关店铺,由于taobao的反爬策略,只能爬取到第十页大概200个店铺的信息. 效果预览 最终爬取的数据用exc ...

  2. python爬虫获取天猫店经营者资质证书(更新到2020.06.13

    python爬虫获取天猫店经营者资质证书(更新到2020.06.13 爬取需求 excel表中给定多个天猫的店铺链接,获取店铺的经营者资质证书,保存为本地图片 代码基于之前写的一个博客https:// ...

  3. Python网络爬虫获取淘宝商品价格

    1.Python网络爬虫获取淘宝商品价格代码: #-*-coding:utf-8-*- ''' Created on 2017年3月17日 @author: lavi ''' import reque ...

  4. 如何使用爬虫采集天猫店铺商品信息

    大数据时代必备技能 - 神箭手云爬虫 -一站式云端通用爬虫开发平台 神箭手云爬虫多样化采集网页内容,快速产生大量而优质的内容. 1.打开神箭手云爬虫官网 2.创建爬虫任务 (1) 在首页点击" ...

  5. Python爬虫获取文章的标题及你的博客的阅读量,评论量。所有数据写入本地记事本。最后输出你的总阅读量!

    Python爬虫获取文章的标题及你的博客的阅读量,评论量.所有数据写入本地记事本.最后输出你的总阅读量!还可以进行筛选输出!比如阅读量大于1000,之类的! 完整代码在最后.依据阅读数量进行降序输出! ...

  6. python Chrome + selenium自动化测试与python爬虫获取网页数据

    一.使用Python+selenium+Chrome 报错: selenium.common.exceptions.SessionNotCreatedException: Message: sessi ...

  7. 域名带后缀_[Python 爬虫]获取顶级域名及对应的 WHOIS Server 及 whoisservers.txt 下载...

    使用 Python 爬虫获取顶级域名及对应的 WHOIS Server 并保存可用于 WhoisCL.exe 的文件 whois-servers.txt. 环境: Windows 10 Python ...

  8. python爬虫获取url_Python爬虫如何获取页面内所有URL链接?本文详解

    如何获取一个页面内所有URL链接?在Python中可以使用urllib对网页进行爬取,然后利用Beautiful Soup对爬取的页面进行解析,提取出所有的URL. 什么是Beautiful Soup ...

  9. python爬虫获取下一页url_Python爬虫获取页面所有URL链接过程详解

    如何获取一个页面内所有URL链接?在python中可以使用urllib对网页进行爬取,然后利用Beautiful Soup对爬取的页面进行解析,提取出所有的URL. 什么是Beautiful Soup ...

最新文章

  1. Linux服务器下安装配置Nginx的教程
  2. 深入浅出设计模式原则之开闭原则(OCP)
  3. 8086汇编贪吃蛇(随机食物+速度递增)
  4. UVA225Golygons 黄金图形
  5. python webservice接口测试传参数_Python3 webservice接口测试方法是什么
  6. 【渝粤教育】电大中专计算机常用工具软件 (2)作业 题库
  7. c mysql 包含字符串_Mysql字符串字段判断是否包含某个字符串的2种方法
  8. vue-cli 发布部署IIS
  9. 安装SharePoint2010的准备工作-2
  10. 关于MDI文件与Microsoft Office Document Imaging
  11. SSD-tensorflow Windows环境下,mAP的计算
  12. PaaS平台案例汇,企业PaaS平台搭建思路
  13. 关于神经网络算法使用场景的思考
  14. div点击穿透,CSS属性pointer-events :none;实现护眼模式, 夜间模式遮罩
  15. Pytorch官方文档个人阅读总结
  16. 游戏里面的英雄是怎么做的?
  17. 纯css position:sticky 实现表格首行和首列固定
  18. 不做etl sql 怎么直接取_不管茄子怎么做,直接下锅是大错!多加1步,茄子更入味,不变色...
  19. CSV格式转换为xlsx格式
  20. oracle应付账款凭证编号查找,记账凭证编号怎么填写 记账凭证编号的规则

热门文章

  1. 计算机科学家格言,未来科技有关名言
  2. linux u盘更新程序,嵌入式linux下插u盘自动更新的设计
  3. 蓝奏云第三方cmd客户端(LanZouCloud-CMD)Cookie内容设置方法
  4. 欧国联 法国 vs 德国
  5. silverlight 学习笔记 (一):silverlight 能做什么
  6. 认识“Silverlight”
  7. 隐藏input文本框的边框
  8. threeJS中4*4矩阵实现平移和旋转的原理
  9. MySQL必知必会笔记(一)基础知识和基本操作
  10. 女性常掉头发的应对法(zt)