Scrapy爬取电商网站京东奶粉商品价格数据-附各种问题解决
2017-10-19 10:24
501 查看
主要的目标是爬奶粉的价格,商品名称和sku_id,想知道奶粉的平均价格。
首先在cmd里建立一个新的scrapy spider project
(1)scrapy startproject milkprice 创建一个项目
(2)创建一个spider,注意要先cd到有.cfg的路径下创建
用scrapy genspider -l 命令可以查看spider模板
scrapy genspider -t <template_name> <spider_name> <domain> 命令可以创建spider
创建好了以后项目文件里会生成scrapy预置的框架,集合了爬取,保存以及一些爬取中的设置。
在spiders文件夹里打开我们刚才命名的那个spider;
name 用于区别不同的spider,我们可以建立多个spider。
start_urls是在spider启动时进行爬取的url列表,可以是一个也可以是多个,可以给一个初始的url,在后面的parse里解析页面时拿到下一页的url然后自动继续爬取或者一开始我们知道每页的url,就可以都放在start_urls里。
京东的商品每页的url长一个样子,只需要该page的数字,所以可以事先都列在这。
spider对每个url会进行访问,得到一个response,然后对这个response解析,生成item对象,送到pipeline里保存我们的数据,同时还能负责生成下一个request对象;
现在我们来定义解析函数parse
我们可以看到每个商品的信息都非常整齐地在li class='gl-item'里呆着,所以我们可以先拿到所有商品的li元素,以便于获取到data-sku属性。
为了取到商品的名称信息,我们先获取到em元素这个selector,然后再逐一取text,可以生成一个商品的名字的列表。
在pipelines里可以用csvitemexporter,jsonitemexporter写入每个item,或者自己定义数据库链接,将数据保存到数据库里。
settings里有诸多有用的控制。比如上面这个。它的默认值是True,但是在爬京东的过程中,没有找到robot.txt,就会不停redirect到京东首页,迟迟不能按照我的url爬。在这里把它改成false就好啦。
设置下载延迟,默认是3,单位是秒,可以有小数点
不向web_server发送cookies,一般为了性能为了反爬最后都禁止。
然后我们可以启动项目scrapy crawl <spider_name>
还可以打开保存的csv查看
下面开始说下项目中遇到的问题:
1. xpath相关:
(1)对selector对象再取xpath的时候,前面一定要加上‘.’,表示选取当前节点
(2)//是相对路径,表示这个元素后所有满足要求的元素,/是绝对路径,表示紧跟其后的
(3)选取根元素后面多个text应该逐一取到这个根元素的selector,然后取text(),可以得到一个text的list
2. scrapy shell相关:
正常我们用scrapy shell调试xpath 可以简简单单的scrapy shell url,但是这次经常打不开正确的url
(1)检查response是不是正确的url的response,可以通过response.url和view(response)在浏览器打开url来检查
(2)先打scrapy shell命令, 然后用fetch('url'),用这个方法竟然就打开了。。。
(3)要传入headers咋办?在scrapy shell 里,
from scrapy import Request
req=Request(url, headers={"ddd" : "dddd",... ...})
fetch(req)
(4)加user agent
4000
scrapy shell -s USER_AGENT='…' url
3. 动态加载问题:
一开始使用的url是进去京东搜索奶粉后的url,但是爬着爬着遇到两个问题
(1)在商品list页面我只能抓到30个,但实际陈列了60个,咋回事呢,原来是需要手动往下拉去加载剩下30个,这也解释了为啥第一页是page=1,第二页就是page=3了,其实是有page=2的...汗,看到了好多按照page=1,3,5,7,9...抓的同学
(2)进入了商品详情url后,发现抓不到价格了,OMG。。。咋回事,发现也变成是js,网页去动态请求了价格数据。
解决方案就是用inspect里的network,看看这些url都默默低做了些啥。
点了network之后刷新页面,然后我们会看到前30个商品的信息;左上角那个ban的符号,是clear已经load好的数据,我们点一下清除第一页的数据;然后把页面往下拉,让页面加载剩下30个商品,然后看到network里面name列里的各种返回数据,同过看他们的response,我们可以找到我们需要的信息。比如说剩下30个信息就藏在这个s_new。。。。request里,在headers里我能看到它的url和headers信息,于是乎,我们就可以用这个url和headers来访问。
4.不按照指定url爬,总是redirect
到settings里修改ROBOTSTXT_OBEY为false
5. 价格获取不到的报错
多爬几页的话就会遇到有些东西价格信息拿不到的情况,为了不影响该页其他商品的爬取,对原代码做一点修正
首先在cmd里建立一个新的scrapy spider project
(1)scrapy startproject milkprice 创建一个项目
(2)创建一个spider,注意要先cd到有.cfg的路径下创建
用scrapy genspider -l 命令可以查看spider模板
scrapy genspider -t <template_name> <spider_name> <domain> 命令可以创建spider
创建好了以后项目文件里会生成scrapy预置的框架,集合了爬取,保存以及一些爬取中的设置。
在spiders文件夹里打开我们刚才命名的那个spider;
class JingdongSpider(scrapy.Spider): name = 'jingdong' allowed_domains = ['search.jd.com'] start_urls = ['https://search.jd.com/s_new.php?keyword=%E5... ...page=1。。。', 'https://search.jd.com/s_new.php?key... ...page=2。。。']
name 用于区别不同的spider,我们可以建立多个spider。
start_urls是在spider启动时进行爬取的url列表,可以是一个也可以是多个,可以给一个初始的url,在后面的parse里解析页面时拿到下一页的url然后自动继续爬取或者一开始我们知道每页的url,就可以都放在start_urls里。
京东的商品每页的url长一个样子,只需要该page的数字,所以可以事先都列在这。
spider对每个url会进行访问,得到一个response,然后对这个response解析,生成item对象,送到pipeline里保存我们的数据,同时还能负责生成下一个request对象;
现在我们来定义解析函数parse
def parse(self, response): """ 直接获取每个sku-data """ product = MilkpriceItem() sku_list = response.xpath('//li[@class="gl-item"]') name_selector = response.xpath('//div[@class="p-name p-name-type-2"]//em') for i in range(len(sku_list)): product['sku_id'] = sku_list[i].xpath('./@data-sku').extract()[0] product['price'] = float(sku_list[i].xpath('.//div[@class="p-price"]//i//text()').extract()[0]) product['brand'] = name_selector[i].xpath('./text()').extract()[0] product['name'] = name_selector[i].xpath('./text()').extract()[1:] yield product
我们可以看到每个商品的信息都非常整齐地在li class='gl-item'里呆着,所以我们可以先拿到所有商品的li元素,以便于获取到data-sku属性。
在pipelines里可以用csvitemexporter,jsonitemexporter写入每个item,或者自己定义数据库链接,将数据保存到数据库里。
from scrapy.exporters import CsvItemExporter class MilkpriceItemCsvPipeline(object): def open_spider(self, spider): self.file = open('milkprice.csv', 'wb') self.exporter = CsvItemExporter(self.file) self.exporter.start_exporting() def close_spider(self, spider): self.exporter.finish_exporting() self.file.close() def process_item(self, item, spider): self.exporter.export_item(item) return item我们修改完pipeline以后,要记得在settings里修改默认值,数字本身没什么特别意义,越大优先级越高,可以列多个,也可以写个jsonItemExporter在里面
ITEM_PIPELINES = { 'milkprice.pipelines.MilkpriceItemCsvPipeline': 300, }
# Obey robots.txt rules ROBOTSTXT_OBEY = False
settings里有诸多有用的控制。比如上面这个。它的默认值是True,但是在爬京东的过程中,没有找到robot.txt,就会不停redirect到京东首页,迟迟不能按照我的url爬。在这里把它改成false就好啦。
DOWNLOAD_DELAY = 10
设置下载延迟,默认是3,单位是秒,可以有小数点
COOKIES_ENABLED = False
不向web_server发送cookies,一般为了性能为了反爬最后都禁止。
DEFAULT_REQUEST_HEADERS = { # "Accept": "*/*", "Accept-Encoding": "gzip, deflate, br", # "Accept-Language": "en-US,en;q=0.8", "Connection": "keep-alive", 。。。 。。。 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36", # "X-Requested-With": "XMLHttpRequest", }添加headers
然后我们可以启动项目scrapy crawl <spider_name>
还可以打开保存的csv查看
下面开始说下项目中遇到的问题:
1. xpath相关:
(1)对selector对象再取xpath的时候,前面一定要加上‘.’,表示选取当前节点
(2)//是相对路径,表示这个元素后所有满足要求的元素,/是绝对路径,表示紧跟其后的
(3)选取根元素后面多个text应该逐一取到这个根元素的selector,然后取text(),可以得到一个text的list
2. scrapy shell相关:
正常我们用scrapy shell调试xpath 可以简简单单的scrapy shell url,但是这次经常打不开正确的url
(1)检查response是不是正确的url的response,可以通过response.url和view(response)在浏览器打开url来检查
(2)先打scrapy shell命令, 然后用fetch('url'),用这个方法竟然就打开了。。。
(3)要传入headers咋办?在scrapy shell 里,
from scrapy import Request
req=Request(url, headers={"ddd" : "dddd",... ...})
fetch(req)
(4)加user agent
4000
scrapy shell -s USER_AGENT='…' url
3. 动态加载问题:
一开始使用的url是进去京东搜索奶粉后的url,但是爬着爬着遇到两个问题
(1)在商品list页面我只能抓到30个,但实际陈列了60个,咋回事呢,原来是需要手动往下拉去加载剩下30个,这也解释了为啥第一页是page=1,第二页就是page=3了,其实是有page=2的...汗,看到了好多按照page=1,3,5,7,9...抓的同学
(2)进入了商品详情url后,发现抓不到价格了,OMG。。。咋回事,发现也变成是js,网页去动态请求了价格数据。
解决方案就是用inspect里的network,看看这些url都默默低做了些啥。
点了network之后刷新页面,然后我们会看到前30个商品的信息;左上角那个ban的符号,是clear已经load好的数据,我们点一下清除第一页的数据;然后把页面往下拉,让页面加载剩下30个商品,然后看到network里面name列里的各种返回数据,同过看他们的response,我们可以找到我们需要的信息。比如说剩下30个信息就藏在这个s_new。。。。request里,在headers里我能看到它的url和headers信息,于是乎,我们就可以用这个url和headers来访问。
4.不按照指定url爬,总是redirect
到settings里修改ROBOTSTXT_OBEY为false
5. 价格获取不到的报错
多爬几页的话就会遇到有些东西价格信息拿不到的情况,为了不影响该页其他商品的爬取,对原代码做一点修正
price = sku_list[i].xpath('.//div[@class="p-price"]//i//text()').extract_first() if price: product['price'] = float(price) else: product['price'] = ''
相关文章推荐
- 开发电商网站遇到的问题、解决方法、心得感想
- 京东价格监控软件开发技术探讨八:如何获取京东商品分类数据
- 百度测试商品搜索 已收录京东等17家网站数据
- 初学大数据之模块集成:Pycharm安装numpy,scipy,sklearn等包时遇到的各种问题的一键解决方法
- 解决 GlobalSign 证书导致 Mac 上京东、淘宝等网站打不开的问题
- 数据模型-电商网站商品的spu和sku数据结构
- MVC发布网站的各种权限问题及解决设置
- 已解决问题:从Excel中读数据到数据库,本地VS运行都成功,网站发布后不能读取数据
- 使用HtmlAgilityPack和ScrapySharp抓取网页数据遇到的几个问题解决方法——格式编码问题
- python数据分析与挖掘学习笔记(6)-电商网站数据分析及商品自动推荐实战与关联规则算法
- 记录:解决2003server中本地网站保存数据到Access中时报错:Operation must use an updateable query 问题
- 【爬虫】利用Scrapy抓取京东商品、豆瓣电影、技术问题
- HTML+CSS:临摹电商网站解决兼容性问题以及心得
- MYSQL主机Master磁盘写满,导致主从数据无法同步各种问题解决
- python数据分析与挖掘学习笔记(6)-电商网站数据分析及商品自动推荐实战与关联规则算法
- 爬虫爬取电商网站的商品数据并保存成json文件
- 大数据实验增加,导致虚拟机的根目录/ 磁盘空间不够,会带来各种问题, 使用gpated工具解决!!
- 解决网站数据显示缓慢的问题
- WebRequest调用数据和解决繁体网站数据的乱码问题
- 68eshop版本 商品价格显示为0 ecshop 解决会员登录后商品价格显示为0的问题