根据用户输入的日期区间,获取已完成和配送中的相关订单信息,并生成表格。
一个订单可能包含多个产品,所以会有重复的订单号出现,其中运费、折扣金额、优惠券支付是根据当前订单中产品数量算出的平均值。

1、创建Scrapy项目

scrapy startproject Order

2.进入项目目录,使用命令genspider创建Spider

scrapy genspider order XXXX.com

3、定义要抓取的数据(处理items.py文件)

# -*- coding: utf-8 -*-
import scrapyclass OrderItem(scrapy.Item):# 序号number = scrapy.Field()# 订单号order_number = scrapy.Field()# 卖家(企业)order_company = scrapy.Field()# 客户信息order_client = scrapy.Field()# 获取订单金额order_money = scrapy.Field()# 下单时间order_time = scrapy.Field()# 订单来源order_source = scrapy.Field()# 订单状态order_state = scrapy.Field()# 签收时间sign_time = scrapy.Field()# 商品名称product_name = scrapy.Field()# 商品分类product_class = scrapy.Field()# 商品金额小计product_money = scrapy.Field()# 平均运费freight = scrapy.Field()# 折扣金额discount_money = scrapy.Field()# 优惠券支付voucher = scrapy.Field()# 查询时间select_time = scrapy.Field()

4、编写提取item数据的Spider(在spiders文件夹下:order.py)

# -*- coding: utf-8 -*-
# 1、根据用户输入的日期区间,获取已完成和配送中的相关订单信息,并生成表格。
# 2、一个订单可能包含多个产品,所以会有重复的订单号出现,其中运费、折扣金额、优惠券支付是根据当前订单中产品数量算出的平均值。import scrapy
import re,time
from Order.items import OrderItemclass OrderSpider(scrapy.Spider):name = 'order'allowed_domains = ['XXXX.com']login_page = "https://pos.XXXX.com/login.html"start_urls = ['https://pos.XXXX.com/order/tolist.html']username = input("请输入账号:")password = input("请输入密码:")def start_requests(self):yield scrapy.Request(url=self.login_page,callback=self.login)def login(self,response):yield scrapy.FormRequest.from_response(response,formdata={"j_username":self.username, "j_password":self.password},callback = self.parse_page)def parse_page(self,response):if "loginerror" in response.body.decode("utf-8"):print("登录失败,错误的手机号或密码")if "</span>首页" in response.body.decode("utf-8"):print("欢迎您'%s',成功登录POS后台管理系统!"%(self.username))yield scrapy.Request(self.start_urls[0],callback=self.order_list)def order_list(self,response):# 存储用户输入的日期,前两个是已完成状态的日期,后两个是配送中的日期self.date_list = []# 日期格式正则规则patt = re.compile(r"\d{4}-\d{1,2}-\d{1,2}")for self.state in ['100','40']:while True:print("\n" + "=" * 87)print("开始日期如果不输入则为2015年最早日期,假设为2015-1-1,结束日期如果不输入则为当天日期。")print("注意:已完成订单中,如果开始和结束日期都不输入,则把签收日期为空的也会筛选出来。")print("=" * 87 + "\n")if self.state == "100":self.start_date = input("请输入已完成签收的开始日期(格式:2018-11-30):")self.end_date = input("请输入已完成签收的结束日期(格式:2018-11-30):")else:self.start_date = input("请输入配送中的下单开始日期(格式:2018-11-30):")self.end_date = input("请输入配送中的下单结束日期(格式:2018-11-30):")re_start_date = patt.findall(self.start_date)re_end_date = patt.findall(self.end_date)if self.start_date != '':if len(re_start_date) != 0:# 结束日期可以不输入if self.end_date == '':breakelse:if len(re_end_date) == 0:print("ERROR:结束日期格式输入有误,请重新输入!")continueelse:breakelse:if self.end_date != '':if len(re_end_date) == 0:print("ERROR:开始和结束日期格式输入有误,请重新输入!")continueelse:print("ERROR:开始日期格式输入有误,请重新输入!")continueelse:if self.end_date != '':if len(re_end_date) == 0:print("ERROR:结束日期格式输入有误,请重新输入!")continueelse:breakelse:breakself.date_list.append(self.start_date)self.date_list.append(self.end_date)yield scrapy.FormRequest.from_response(response,formdata={# "d-5481-p": "1","to.buyer": "","to.endDate": self.end_date,"to.id": "",# 订单状态,-1代表全部"to.orderSource": "-1","to.seller": "","to.startDate": self.start_date,# 已完成是100,配送中是40"to.status": self.state,},callback=self.parse)# print("退出系统。。。") # 这个无法实现,未等产品获取完毕系统就已退出导致获取不到数据# yield scrapy.Request('https://pos.XXXX.com/j_spring_security_logout')def parse(self, response):# 获取当天的日期today_time = time.strftime("%Y-%m-%d", time.localtime())if self.date_list[1] == '':self.date_list[1] = today_timeif self.date_list[3] == '':self.date_list[3] = today_timeif self.date_list[0] == '':self.date_list[0] = '2015-1-1'if self.date_list[2] == '':self.date_list[2] = '2015-1-1'items = []next_url_list = list(set(response.xpath('//span[@class="pagelinks"]/a/@href').extract()))# 获取查询结果的数据,计算有多少页,是一个列表# page_list = response.xpath('//*[@id="signForm"]/span[1]/text()').extract()# if len(page_list) == 0:#     print("抱歉,没有查询到相应条件的商品!")# else:#     # 如果只有一条数据会显示One#     if page_list[0].split(" ")[0] != "One":#         total = int(page_list[0].split(" ")[0].replace(",", ""))#     else:#         total = 1#     if total % 20 == 0:#         end_page = total // 20#         print('共获取到%d项订单数据,合计%d页' % (total, end_page))#     else:#         end_page = total // 20 + 1#         print('共获取到%d项订单数据,合计%d页' % (total, end_page))order_state = ""for each in response.xpath('//div[@class="dataTables_wrapper"]'):# 序号number = each.xpath('//*[@id="to"]/tbody/tr/td[1]/text()').extract()# 订单号order_number = each.xpath('//*[@id="to"]/tbody/tr/td[2]/a/text()').extract()# 卖家(企业)order_company = each.xpath('//*[@id="to"]/tbody/tr/td[3]/a/text()').extract()# 客户信息order_client = each.xpath('//*[@id="to"]/tbody/tr/td[4]/text()').extract()# 获取订单金额order_money = each.xpath('//*[@id="to"]/tbody/tr/td[5]/text()').extract()# 下单时间,首尾无空格order_time = each.xpath('//*[@id="to"]/tbody/tr/td[6]/text()').extract()# 订单来源order_source = each.xpath('//*[@id="to"]/tbody/tr/td[10]/text()').extract()# 订单状态order_state = each.xpath('//*[@id="to"]/tbody/tr/td[11]/text()').extract()# 签收时间sign_time = each.xpath('//*[@id="to"]/tbody/tr/td[7]/text()').extract()for i in range(len(number)):item = OrderItem()item['number'] = number[i].strip()item['order_number'] = order_number[i].strip()item['order_company'] = order_company[i].replace("\n", "").replace("\t", "").replace("\r", "").\replace(" ","").replace(" ", "").strip()item['order_client'] = order_client[i].strip()item['order_money'] = order_money[i].strip()item['order_time'] = order_time[i].strip()item['order_source'] = order_source[i].strip()item['order_state'] = order_state[i].strip()if order_state[0].strip() == "已完成":item['sign_time'] = sign_time[i].strip()item['select_time'] = "查询签收日期:"+self.date_list[0]+"至"+self.date_list[1]# 配送中的订单没有签收时间else:item['sign_time'] = ""item['select_time'] = "查询下单日期:" + self.date_list[2] + "至" + self.date_list[3]items.append(item)# 根据订单号获取到产品链接for item in items:id_url = 'https://pos.XXXX.com/order/showto.html?to.id='+item['order_number']yield scrapy.Request(url=id_url,meta={'meta_1':item},callback=self.parse_id)# 处理下一页for page in next_url_list:if page[10:11] != '1':print("总共%s页,订单状态:%s"%((page[10:11]),order_state[0].strip()))order_list_url = "https://pos.XXXX.com/order/tolist.html" + str(page)# 无需处理第一页,因为order_list传过来的response已经处理yield scrapy.Request(url = order_list_url,callback=self.parse)# 根据订单号获取产品名称和运费、价格等def parse_id(self,response):meta_1 = response.meta['meta_1']item = OrderItem()# with open(meta_1['order_number']+".html","w",encoding='utf-8')as f:#     f.write(response.text)# 获取商品名称,注意xpath的规则,//tr而不是/tbody/tr,有些是浏览器自动加的product_name = response.xpath('//*[@id="order_items"]//tr/td[1]/text()').extract()# product_name = response.xpath('//*[@id="order_items"]/tbody/tr/td[1]/text()').extract()# 获取商品分类# product_class = response.xpath('//div[@id="tabs-2"]/table[@id="order_items"]/tbody/tr/td[2]/text()').extract()product_class = response.xpath('//*[@id="order_items"]//tr/td[2]/text()').extract()# 商品金额小计product_money = response.xpath('//*[@id="order_items"]//tr/td[6]/text()').extract()# 运费,平分freight = response.xpath('//*[@id="order_items"]//tr[2]/th[2]/span/text()').extract()# 折扣金额,平分discount_money = response.xpath('//*[@id="order_items"]//tr[3]/th[2]/text()').extract()# 优惠券支付,平分voucher = response.xpath('//*[@id="order_items"]//tr[5]/th[2]/text()').extract()# 获取该订单下有多少个产品分类length = len(product_name)print("状态:%s,订单号:%s,有%s个产品,处理中...."%(meta_1['order_state'],meta_1['order_number'],length))for i in range(length):item['product_name'] = product_name[i].strip()item['product_class'] = product_class[i].strip()item['product_money'] = product_money[i].strip()item['freight'] = float(freight[0].strip())/lengthitem['discount_money'] = float(discount_money[0].strip())/lengthitem['voucher'] = float(voucher[0].strip())/lengthitem['number'] = meta_1['number']item['order_number'] = meta_1['order_number']item['order_company'] = meta_1['order_company']item['order_client'] = meta_1['order_client']item['order_money'] = meta_1['order_money']item['order_time'] = meta_1['order_time']item['order_source'] = meta_1['order_source']item['order_state'] = meta_1['order_state']item['sign_time'] = meta_1['sign_time']item['select_time'] = meta_1['select_time']yield item

5.处理pipelines管道文件保存数据,可将结果保存到文件中(pipelines.py)

# -*- coding: utf-8 -*-
import json
from openpyxl import Workbook
import time# 转码操作,继承json.JSONEncoder的子类
class MyEncoder(json.JSONEncoder):def default(self, o):if isinstance(o, bytes):return str(o, encoding='utf-8')return json.JSONEncoder.default(self, o)class OrderPipeline(object):def __init__(self):self.wb = Workbook()self.ws = self.wb.activeself.ws.title = '订单数量列表'# 冻结首行self.ws.freeze_panes = 'A2'self.ws.column_dimensions['C'].width = 19self.ws.column_dimensions['D'].width = 21self.ws.column_dimensions['J'].width = 23self.ws.column_dimensions['N'].width = 9.4self.ws.column_dimensions['O'].width = 18self.ws.column_dimensions['P'].width = 35# 创建表头self.ws.append(['序号', '订单号', '卖家', '客户','订单金额', '下单时间','订单来源', '订单状态', '商品名称','商品分类','商品金额小计','平均运费','折扣金额','优惠券支付','签收时间','查询日期'])def process_item(self, item, spider):text = [item['number'], item['order_number'], item['order_company'], item['order_client'],item['order_money'], item['order_time'],item['order_source'], item['order_state'], item['product_name'],item['product_class'],item['product_money'],item['freight'],item['discount_money'],item['voucher'],item['sign_time'],item['select_time']]self.ws.append(text)return itemdef close_spider(self, spider):# 给保存的文件名字加上个当天的日期年月日file_end_name = time.strftime("%Y-%m-%d", time.localtime())self.wb.save("订单数量列表" + file_end_name + '.xlsx')print("数据处理完毕,谢谢使用!")

6.配置settings文件(settings.py)

# Obey robots.txt rules,具体含义参照:https://blog.csdn.net/z564359805/article/details/80691677
ROBOTSTXT_OBEY = False  # Override the default request headers:添加User-Agent信息
DEFAULT_REQUEST_HEADERS = {      'User-Agent': 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0);',      # 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',      # 'Accept-Language': 'en',
}  # Configure item pipelines去掉下面注释,打开管道文件
ITEM_PIPELINES = {      'Order.pipelines.OrderPipeline': 300,
}  # 还可以将日志存到本地文件中(可选添加设置)
LOG_FILE = "order.log"
LOG_LEVEL = "DEBUG"
# 包含打印信息也一起写进日志里
LOG_STDOUT = True

7.以上设置完毕,进行爬取:执行项目命令crawl,启动Spider:

scrapy crawl order

python3.6 scrapy模块查询POS后台获取指定时间和状态的订单存入到excel表格中相关推荐

  1. Java中时间格式化(获取指定时间)

    Java中时间格式化(获取指定时间,七天前) 1.通过获取当前系统时间,格式化后转为"yyyy-MM-dd HH:mm:ss"格式并输出: 2.可获取指定时间,如七天前,一年前等, ...

  2. python3读取excel数据-python3 读取Excel表格中的数据

    需要先安装openpyxl库 通过pip命令安装: pip install openpyxl 源码如下: #!/usr/bin/python3 #-*- coding:utf-8 -*- import ...

  3. 获取指定时间的当天时间范围工具类

    /*** 获取指定时间的当天时间范围* @param date*/public static Date[] getTimeRangeDay(Date date){Date[] timeRange = ...

  4. 查询oracle数据库的表格数据类型,excel表格中如何查询数据库数据类型-我想把excel表格中的数据导入oracle数据库中,想在......

    在excel表里,什么是:字段.记录.数据类型.多工... declare @t table(id numeric(18,2)) insert into @t SELECT   col1 FROM   ...

  5. 获取指定年份的工作日和节假日后导入Excel

    github地址 本文主要是获取指定年份的工作日和节假日后导入Excel 1.获取指定年份的所有日期,默认周一到周五是工作日,周六和周日是节假日. 2.获取国家法定节假日和对应调休日期. 3.修改法定 ...

  6. java中获取指定时间的时间戳

    在 Java 中,可以使用 Instant 类来获取指定时间的时间戳. 首先,你需要使用 ZonedDateTime 类来表示指定的时间.你可以使用 ZonedDateTime.of 方法来创建一个 ...

  7. Java获取指定时间之后的几分钟

    1.获取指定时间之后的几分钟 public static String getFiveMinAfter(String time) throws ParseException {SimpleDateFo ...

  8. 获取指定时间的那天 23:59:59.999 的时间

    一.环境介绍 1.Java编程中,需要实现创建获取指定时间的那天23:59:59.999的时间,并且返回值为日期Date类型的实现方法和函数,下面是我写的代码,仅供参考使用: /** * 获取指定时间 ...

  9. Vue获取当前日期时间、获取指定时间的前、后多少天的日期

    https://blog.csdn.net/ForeverBana/article/details/103472751  Vue获取当前日期 https://blog.csdn.net/weixin_ ...

  10. 15、【 商品管理模块开发】——后台获取商品详情功能开发及PropertiesUtil配置工具,DateTimeUtil时间处理工具开发...

    1.后台获取商品详情接口: 在上一篇文章所新建的ProudctManageController类中新建下面方法: *Controller: //获取商品详情接口@RequestMapping(&quo ...

最新文章

  1. CVPR2020:基于自适应采样的非局部神经网络鲁棒点云处理(PointASNL)
  2. top_k问题python解
  3. leetcode算法题--二叉树中序遍历迭代法
  4. sqlite字段是否存在_学习廖雪峰的JAVA教程---反射(访问字段)
  5. LeetCode 874. 模拟行走机器人(set)
  6. R语言编程基础(2)
  7. 怎么查看页面跳转过程_fastcapture注册码怎么获取?FastStone注册码分享
  8. 同类型的免费下载软件中, JDownloader的功能比FreeRapid Downloader功能要强很多
  9. 开源微服务框架 汇总
  10. 20155313 杨瀚 《网络对抗技术》实验二 后门原理与实践
  11. ibus中文拼音输入法安装以及遇到问题解决办法
  12. JAVA ——线程概念(线程的生命周期及使用)
  13. 使用xlwt将数据保存到excel文件中,python
  14. Mac上启动、关闭、重启MySQL服务
  15. 基于Java毕业设计大学生兼职网站源码+系统+mysql+lw文档+部署软件
  16. VO、DTO、BO、QO、DO 如何使用,在那一层使用,一张图告诉你;别再纠结命名规则啦,我来告诉你
  17. 数理统计(四)-方差分析及回归分析:总变差分解【总变差=方差+效应A平方和+效应B平方和+AB交互效应平方和】、线性回归模型、回归方程、残差、残差平方和、σ的无偏估计、多元线性回归模型、非线性回归模型
  18. k线顶分型 python_日线顶分型是什么意思?k线顶分型图解与操作要领
  19. 上海某软件公司电话面试分享
  20. 康益明爱崔紫娟-很爱很爱

热门文章

  1. axure8下拉表单_AXURE RP 8怎么设置下拉菜单? AXURE下拉菜单的制作方法
  2. PS修改图片尺寸和大小
  3. 第3章 网站评价准则和色彩心理学
  4. Joson的简单用法
  5. python卖水果_用Python解决一个简单的水果分类问题
  6. noi linux 比赛使用哪个编译器,noi linux简介.pdf
  7. 含有n个元素的整型数组,将这个n个元素重新组合,求出最小的数,如{321,3,32},最小的数为321323...
  8. 千篇一律的秃顶,各有各的顽皮,1组图让你了解程序员的可爱
  9. WIN10教育版怎么可以变更为专业版
  10. 证明:一个有n个结点的非空二叉树的高度至少为lgn