python爬虫--获取天猫店铺商品价格及销量
(一)项目目标
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爬虫--获取天猫店铺商品价格及销量相关推荐
- python爬虫获取天猫店铺信息(更新到2020年)
python爬虫获取天猫店铺信息 爬取需求 在天猫搜索一个关键词,然后抓取这个关键词下的相关店铺,由于taobao的反爬策略,只能爬取到第十页大概200个店铺的信息. 效果预览 最终爬取的数据用exc ...
- python爬虫获取天猫店经营者资质证书(更新到2020.06.13
python爬虫获取天猫店经营者资质证书(更新到2020.06.13 爬取需求 excel表中给定多个天猫的店铺链接,获取店铺的经营者资质证书,保存为本地图片 代码基于之前写的一个博客https:// ...
- Python网络爬虫获取淘宝商品价格
1.Python网络爬虫获取淘宝商品价格代码: #-*-coding:utf-8-*- ''' Created on 2017年3月17日 @author: lavi ''' import reque ...
- 如何使用爬虫采集天猫店铺商品信息
大数据时代必备技能 - 神箭手云爬虫 -一站式云端通用爬虫开发平台 神箭手云爬虫多样化采集网页内容,快速产生大量而优质的内容. 1.打开神箭手云爬虫官网 2.创建爬虫任务 (1) 在首页点击" ...
- Python爬虫获取文章的标题及你的博客的阅读量,评论量。所有数据写入本地记事本。最后输出你的总阅读量!
Python爬虫获取文章的标题及你的博客的阅读量,评论量.所有数据写入本地记事本.最后输出你的总阅读量!还可以进行筛选输出!比如阅读量大于1000,之类的! 完整代码在最后.依据阅读数量进行降序输出! ...
- python Chrome + selenium自动化测试与python爬虫获取网页数据
一.使用Python+selenium+Chrome 报错: selenium.common.exceptions.SessionNotCreatedException: Message: sessi ...
- 域名带后缀_[Python 爬虫]获取顶级域名及对应的 WHOIS Server 及 whoisservers.txt 下载...
使用 Python 爬虫获取顶级域名及对应的 WHOIS Server 并保存可用于 WhoisCL.exe 的文件 whois-servers.txt. 环境: Windows 10 Python ...
- python爬虫获取url_Python爬虫如何获取页面内所有URL链接?本文详解
如何获取一个页面内所有URL链接?在Python中可以使用urllib对网页进行爬取,然后利用Beautiful Soup对爬取的页面进行解析,提取出所有的URL. 什么是Beautiful Soup ...
- python爬虫获取下一页url_Python爬虫获取页面所有URL链接过程详解
如何获取一个页面内所有URL链接?在python中可以使用urllib对网页进行爬取,然后利用Beautiful Soup对爬取的页面进行解析,提取出所有的URL. 什么是Beautiful Soup ...
最新文章
- Linux服务器下安装配置Nginx的教程
- 深入浅出设计模式原则之开闭原则(OCP)
- 8086汇编贪吃蛇(随机食物+速度递增)
- UVA225Golygons 黄金图形
- python webservice接口测试传参数_Python3 webservice接口测试方法是什么
- 【渝粤教育】电大中专计算机常用工具软件 (2)作业 题库
- c mysql 包含字符串_Mysql字符串字段判断是否包含某个字符串的2种方法
- vue-cli 发布部署IIS
- 安装SharePoint2010的准备工作-2
- 关于MDI文件与Microsoft Office Document Imaging
- SSD-tensorflow Windows环境下,mAP的计算
- PaaS平台案例汇,企业PaaS平台搭建思路
- 关于神经网络算法使用场景的思考
- div点击穿透,CSS属性pointer-events :none;实现护眼模式, 夜间模式遮罩
- Pytorch官方文档个人阅读总结
- 游戏里面的英雄是怎么做的?
- 纯css position:sticky 实现表格首行和首列固定
- 不做etl sql 怎么直接取_不管茄子怎么做,直接下锅是大错!多加1步,茄子更入味,不变色...
- CSV格式转换为xlsx格式
- oracle应付账款凭证编号查找,记账凭证编号怎么填写 记账凭证编号的规则