예제 #1
0
    def start_requests(self):
        """
        爬虫默认接口,启动方法
        :return:
        """
        # 获取爬取时传过来的参数
        # start_time: 开始时间
        # end_time: 结束时间
        # start_page: 开始页 (优先于start_time)
        # end_page: 结束页 (优先于end_time)
        # stop_item: 连续遇到[stop_item]个重复条目后,退出本次爬取
        # spider_name: 指定的spider_name,如果不指定,使用self.name
        # command example:
        # py -3 -m scrapy crawl base_spider -a start_time="2019:01:01" -a end_time="2019:01:02"
        # python3  -m scrapy crawl bjggzyjy_spider -a start_time="now" -a end_time="now"
        # py -3 -m scrapy crawl base_spider -a start_time="now" -a end_time="now" -a start_page="700" -a end_page="1000" -a stop_item="10000"
        assert self.start_time is not None
        assert self.end_time is not None

        self.crawl_mode = CrawlMode.REAL_TIME if str(self.start_time).lower() == 'now' else CrawlMode.HISTORY

        if self.crawl_mode == CrawlMode.HISTORY:
            if (len(self.start_time) != 10 or len(self.end_time) != 10
                    or self.start_time[4] != ':' or self.end_time[4] != ':'):
                logging.error('Bad date format start_time:[{}] end_time:[{}]. Example: 2019:01:01'.format(
                    self.start_time, self.end_time))
                return
        else:
            # 取当天日期
            _dt = datetime.fromtimestamp(time.time())
            self.start_time = _dt.strftime("%Y:%m:%d")
            self.end_time = self.start_time

        # 初始化self.crawl_helper
        self.init_crawl_helper()

        # 主要配置项
        _source_info = {
            # 页面的key,保证唯一
            'page_1': {
                # 通常会被填充在'source'字段里,有时也可以放在'tos'
                'name': '北京公共资源交易网',

                # list页面的base地址
                'base_url': 'https://ggzyfw.beijing.gov.cn/',

                # list页面的call_back处理函数
                'callback': self.parse_list_page_common,

                # 得到下一页url的函数,返回值一定是一个url
                'get_next_page_url': self.get_normal_next_page_url,

                # 网站中该页面的最大页数,(可选配置,仅为优化程序执行效率,可不填)
                'stop_page_num': 7000000,

                # 连续遇到[stop_dup_item_num]个重复条目后,停止本次抓取
                # 提示:在程序运行初始阶段,此值可以设的较大,以便爬取所有的历史记录
                'stop_dup_item_num': 500000 if self.crawl_mode == CrawlMode.HISTORY else 60,

                # list页面中,获得条目列表的xpath
                'xpath_of_list': '//ul[@class="article-list2"]/li',

                # 获得每一个条目链接地址的xpath
                'xpath_of_detail_url': './a/@href',

                # 对每一个条目进行解析,返回CommonRawItem的类,需要实现
                'item_parse_class': BaseItemCommonParser,

                # 其它信息,可以辅助生成CommonRawItem的字段
                # 参考函数parse_list_page_common() 中 item_parser.get_common_raw_item()代码
                'tos': '工程建设',
                'tos_code': '01',
                'notice_type': '招标计划',
                'notice_type_code': '0101',
                'source': '北京公共资源交易网',
                'site_name': '北京公共资源交易网',
                'area_code': '11',
                'content_code': '1',
                'bid_sort': 'jyxxgcjszbjh',
                'industryName': '',
                'time_type': 6 if self.crawl_mode == CrawlMode.HISTORY else 0,
            },

            'page_2': {
                # 通常会被填充在'source'字段里,有时也可以放在'tos'
                'name': '北京公共资源交易网',

                # list页面的base地址
                'base_url': 'https://ggzyfw.beijing.gov.cn/',

                # list页面的call_back处理函数
                'callback': self.parse_list_page_common,

                # 得到下一页url的函数,返回值一定是一个url
                'get_next_page_url': self.get_normal_next_page_url,

                # 网站中该页面的最大页数,(可选配置,仅为优化程序执行效率,可不填)
                'stop_page_num': 7000000,

                # 连续遇到[stop_dup_item_num]个重复条目后,停止本次抓取
                # 提示:在程序运行初始阶段,此值可以设的较大,以便爬取所有的历史记录
                'stop_dup_item_num': 500000 if self.crawl_mode == CrawlMode.HISTORY else 60,

                # list页面中,获得条目列表的xpath
                'xpath_of_list': '//ul[@class="article-list2"]/li',

                # 获得每一个条目链接地址的xpath
                'xpath_of_detail_url': './a/@href',

                # 对每一个条目进行解析,返回CommonRawItem的类,需要实现
                'item_parse_class': BaseItemCommonParser,

                # 其它信息,可以辅助生成CommonRawItem的字段
                # 参考函数parse_list_page_common() 中 item_parser.get_common_raw_item()代码
                'tos': '工程建设',
                'tos_code': '01',
                'notice_type': '招标公告',
                'notice_type_code': '0101',
                'source': '北京公共资源交易网',
                'site_name': '北京公共资源交易网',
                'area_code': '11',
                'content_code': '1',
                'bid_sort': 'jyxxggjtbyqs',
                'industryName': '',
                'time_type': 6 if self.crawl_mode == CrawlMode.HISTORY else 0,
            },
            'page_3': {
                # 通常会被填充在'source'字段里,有时也可以放在'tos'
                'name': '北京公共资源交易网',

                # list页面的base地址
                'base_url': 'https://ggzyfw.beijing.gov.cn/',

                # list页面的call_back处理函数
                'callback': self.parse_list_page_common,

                # 得到下一页url的函数,返回值一定是一个url
                'get_next_page_url': self.get_normal_next_page_url,

                # 网站中该页面的最大页数,(可选配置,仅为优化程序执行效率,可不填)
                'stop_page_num': 7000000,

                # 连续遇到[stop_dup_item_num]个重复条目后,停止本次抓取
                # 提示:在程序运行初始阶段,此值可以设的较大,以便爬取所有的历史记录
                'stop_dup_item_num': 500000 if self.crawl_mode == CrawlMode.HISTORY else 60,

                # list页面中,获得条目列表的xpath
                'xpath_of_list': '//ul[@class="article-list2"]/li',

                # 获得每一个条目链接地址的xpath
                'xpath_of_detail_url': './a/@href',

                # 对每一个条目进行解析,返回CommonRawItem的类,需要实现
                'item_parse_class': BaseItemCommonParser,

                # 其它信息,可以辅助生成CommonRawItem的字段
                # 参考函数parse_list_page_common() 中 item_parser.get_common_raw_item()代码
                'tos': '工程建设',
                'tos_code': '01',
                'notice_type': '中标候选人公示',
                'notice_type_code': '0104',
                'source': '北京公共资源交易网',
                'site_name': '北京公共资源交易网',
                'area_code': '11',
                'content_code': '1',
                'bid_sort': 'jyxxzbhxrgs',
                'industryName': '',
                'time_type': 6 if self.crawl_mode == CrawlMode.HISTORY else 0,
            },

            'page_4': {
                # 通常会被填充在'source'字段里,有时也可以放在'tos'
                'name': '北京公共资源交易网',

                # list页面的base地址
                'base_url': 'https://ggzyfw.beijing.gov.cn/',

                # list页面的call_back处理函数
                'callback': self.parse_list_page_common,

                # 得到下一页url的函数,返回值一定是一个url
                'get_next_page_url': self.get_normal_next_page_url,

                # 网站中该页面的最大页数,(可选配置,仅为优化程序执行效率,可不填)
                'stop_page_num': 7000000,

                # 连续遇到[stop_dup_item_num]个重复条目后,停止本次抓取
                # 提示:在程序运行初始阶段,此值可以设的较大,以便爬取所有的历史记录
                'stop_dup_item_num': 500000 if self.crawl_mode == CrawlMode.HISTORY else 60,

                # list页面中,获得条目列表的xpath
                'xpath_of_list': '//ul[@class="article-list2"]/li',

                # 获得每一个条目链接地址的xpath
                'xpath_of_detail_url': './a/@href',

                # 对每一个条目进行解析,返回CommonRawItem的类,需要实现
                'item_parse_class': BaseItemCommonParser,

                # 其它信息,可以辅助生成CommonRawItem的字段
                # 参考函数parse_list_page_common() 中 item_parser.get_common_raw_item()代码
                'tos': '工程建设',
                'tos_code': '01',
                'notice_type': '中标结果',
                'notice_type_code': '0104',
                'source': '北京公共资源交易网',
                'site_name': '北京公共资源交易网',
                'area_code': '11',
                'content_code': '1',
                'bid_sort': 'jyxxzbgg',
                'industryName': '',
                'time_type': 6 if self.crawl_mode == CrawlMode.HISTORY else 0,
            },

            'page_5': {
                # 通常会被填充在'source'字段里,有时也可以放在'tos'
                'name': '北京公共资源交易网',

                # list页面的base地址
                'base_url': 'https://ggzyfw.beijing.gov.cn/',

                # list页面的call_back处理函数
                'callback': self.parse_list_page_common,

                # 得到下一页url的函数,返回值一定是一个url
                'get_next_page_url': self.get_normal_next_page_url,

                # 网站中该页面的最大页数,(可选配置,仅为优化程序执行效率,可不填)
                'stop_page_num': 7000000,

                # 连续遇到[stop_dup_item_num]个重复条目后,停止本次抓取
                # 提示:在程序运行初始阶段,此值可以设的较大,以便爬取所有的历史记录
                'stop_dup_item_num': 500000 if self.crawl_mode == CrawlMode.HISTORY else 60,

                # list页面中,获得条目列表的xpath
                'xpath_of_list': '//ul[@class="article-list2"]/li',

                # 获得每一个条目链接地址的xpath
                'xpath_of_detail_url': './a/@href',

                # 对每一个条目进行解析,返回CommonRawItem的类,需要实现
                'item_parse_class': BaseItemCommonParser,

                # 其它信息,可以辅助生成CommonRawItem的字段
                # 参考函数parse_list_page_common() 中 item_parser.get_common_raw_item()代码
                'tos': '政府采购',
                'tos_code': '02',
                'notice_type': '采购公告',
                'notice_type_code': '0101',
                'source': '北京公共资源交易网',
                'site_name': '北京公共资源交易网',
                'area_code': '11',
                'content_code': '1',
                'bid_sort': 'jyxxcggg',
                'industryName': '',
                'time_type': 6 if self.crawl_mode == CrawlMode.HISTORY else 0,
            },

            'page_6': {
                # 通常会被填充在'source'字段里,有时也可以放在'tos'
                'name': '北京公共资源交易网',

                # list页面的base地址
                'base_url': 'https://ggzyfw.beijing.gov.cn/',

                # list页面的call_back处理函数
                'callback': self.parse_list_page_common,

                # 得到下一页url的函数,返回值一定是一个url
                'get_next_page_url': self.get_normal_next_page_url,

                # 网站中该页面的最大页数,(可选配置,仅为优化程序执行效率,可不填)
                'stop_page_num': 7000000,

                # 连续遇到[stop_dup_item_num]个重复条目后,停止本次抓取
                # 提示:在程序运行初始阶段,此值可以设的较大,以便爬取所有的历史记录
                'stop_dup_item_num': 500000 if self.crawl_mode == CrawlMode.HISTORY else 60,

                # list页面中,获得条目列表的xpath
                'xpath_of_list': '//ul[@class="article-list2"]/li',

                # 获得每一个条目链接地址的xpath
                'xpath_of_detail_url': './a/@href',

                # 对每一个条目进行解析,返回CommonRawItem的类,需要实现
                'item_parse_class': BaseItemCommonParser,

                # 其它信息,可以辅助生成CommonRawItem的字段
                # 参考函数parse_list_page_common() 中 item_parser.get_common_raw_item()代码
                'tos': '政府采购',
                'tos_code': '02',
                'notice_type': '更正事项',
                'notice_type_code': '0204',
                'source': '北京公共资源交易网',
                'site_name': '北京公共资源交易网',
                'area_code': '11',
                'content_code': '1',
                'bid_sort': 'jyxxgzsx',
                'industryName': '',
                'time_type': 6 if self.crawl_mode == CrawlMode.HISTORY else 0,
            },

            'page_7': {
                # 通常会被填充在'source'字段里,有时也可以放在'tos'
                'name': '北京公共资源交易网',

                # list页面的base地址
                'base_url': 'https://ggzyfw.beijing.gov.cn/',

                # list页面的call_back处理函数
                'callback': self.parse_list_page_common,

                # 得到下一页url的函数,返回值一定是一个url
                'get_next_page_url': self.get_normal_next_page_url,

                # 网站中该页面的最大页数,(可选配置,仅为优化程序执行效率,可不填)
                'stop_page_num': 7000000,

                # 连续遇到[stop_dup_item_num]个重复条目后,停止本次抓取
                # 提示:在程序运行初始阶段,此值可以设的较大,以便爬取所有的历史记录
                'stop_dup_item_num': 500000 if self.crawl_mode == CrawlMode.HISTORY else 60,

                # list页面中,获得条目列表的xpath
                'xpath_of_list': '//ul[@class="article-list2"]/li',

                # 获得每一个条目链接地址的xpath
                'xpath_of_detail_url': './a/@href',

                # 对每一个条目进行解析,返回CommonRawItem的类,需要实现
                'item_parse_class': BaseItemCommonParser,

                # 其它信息,可以辅助生成CommonRawItem的字段
                # 参考函数parse_list_page_common() 中 item_parser.get_common_raw_item()代码
                'tos': '政府采购',
                'tos_code': '02',
                'notice_type': '成交结果公示',
                'notice_type_code': '0202',
                'source': '北京公共资源交易网',
                'site_name': '北京公共资源交易网',
                'area_code': '11',
                'content_code': '1',
                'bid_sort': 'jyxxzbjggg',
                'industryName': '',
                'time_type': 6 if self.crawl_mode == CrawlMode.HISTORY else 0,
            },

            'page_8': {
                # 通常会被填充在'source'字段里,有时也可以放在'tos'
                'name': '北京公共资源交易网',

                # list页面的base地址
                'base_url': 'https://ggzyfw.beijing.gov.cn/',

                # list页面的call_back处理函数
                'callback': self.parse_list_page_common,

                # 得到下一页url的函数,返回值一定是一个url
                'get_next_page_url': self.get_normal_next_page_url,

                # 网站中该页面的最大页数,(可选配置,仅为优化程序执行效率,可不填)
                'stop_page_num': 7000000,

                # 连续遇到[stop_dup_item_num]个重复条目后,停止本次抓取
                # 提示:在程序运行初始阶段,此值可以设的较大,以便爬取所有的历史记录
                'stop_dup_item_num': 500000 if self.crawl_mode == CrawlMode.HISTORY else 60,

                # list页面中,获得条目列表的xpath
                'xpath_of_list': '//ul[@class="article-list2"]/li',

                # 获得每一个条目链接地址的xpath
                'xpath_of_detail_url': './a/@href',

                # 对每一个条目进行解析,返回CommonRawItem的类,需要实现
                'item_parse_class': BaseItemCommonParser,

                # 其它信息,可以辅助生成CommonRawItem的字段
                # 参考函数parse_list_page_common() 中 item_parser.get_common_raw_item()代码
                'tos': '土地使用权',
                'tos_code': '03',
                'notice_type': '招拍挂公告',
                'notice_type_code': '0301',
                'source': '北京公共资源交易网',
                'site_name': '北京公共资源交易网',
                'area_code': '11',
                'content_code': '1',
                'bid_sort': 'jyxxzpggg',
                'industryName': '',
                'time_type': 6 if self.crawl_mode == CrawlMode.HISTORY else 0,
            },

            'page_9': {
                # 通常会被填充在'source'字段里,有时也可以放在'tos'
                'name': '北京公共资源交易网',

                # list页面的base地址
                'base_url': 'https://ggzyfw.beijing.gov.cn/',

                # list页面的call_back处理函数
                'callback': self.parse_list_page_common,

                # 得到下一页url的函数,返回值一定是一个url
                'get_next_page_url': self.get_normal_next_page_url,

                # 网站中该页面的最大页数,(可选配置,仅为优化程序执行效率,可不填)
                'stop_page_num': 7000000,

                # 连续遇到[stop_dup_item_num]个重复条目后,停止本次抓取
                # 提示:在程序运行初始阶段,此值可以设的较大,以便爬取所有的历史记录
                'stop_dup_item_num': 500000 if self.crawl_mode == CrawlMode.HISTORY else 60,

                # list页面中,获得条目列表的xpath
                'xpath_of_list': '//ul[@class="article-list2"]/li',

                # 获得每一个条目链接地址的xpath
                'xpath_of_detail_url': './a/@href',

                # 对每一个条目进行解析,返回CommonRawItem的类,需要实现
                'item_parse_class': BaseItemCommonParser,

                # 其它信息,可以辅助生成CommonRawItem的字段
                # 参考函数parse_list_page_common() 中 item_parser.get_common_raw_item()代码
                'tos': '土地使用权',
                'tos_code': '03',
                'notice_type': '招拍挂结果公示',
                'notice_type_code': '0302',
                'source': '北京公共资源交易网',
                'site_name': '北京公共资源交易网',
                'area_code': '11',
                'content_code': '1',
                'bid_sort': 'jyxxzpgjggs',
                'industryName': '',
                'time_type': 6 if self.crawl_mode == CrawlMode.HISTORY else 0,
            },

            'page_10': {
                # 通常会被填充在'source'字段里,有时也可以放在'tos'
                'name': '北京公共资源交易网',

                # list页面的base地址
                'base_url': 'https://ggzyfw.beijing.gov.cn/',

                # list页面的call_back处理函数
                'callback': self.parse_list_page_common,

                # 得到下一页url的函数,返回值一定是一个url
                'get_next_page_url': self.get_normal_next_page_url,

                # 网站中该页面的最大页数,(可选配置,仅为优化程序执行效率,可不填)
                'stop_page_num': 7000000,

                # 连续遇到[stop_dup_item_num]个重复条目后,停止本次抓取
                # 提示:在程序运行初始阶段,此值可以设的较大,以便爬取所有的历史记录
                'stop_dup_item_num': 500000 if self.crawl_mode == CrawlMode.HISTORY else 60,

                # list页面中,获得条目列表的xpath
                'xpath_of_list': '//ul[@class="article-list2"]/li',

                # 获得每一个条目链接地址的xpath
                'xpath_of_detail_url': './a/@href',

                # 对每一个条目进行解析,返回CommonRawItem的类,需要实现
                'item_parse_class': BaseItemCommonParser,

                # 其它信息,可以辅助生成CommonRawItem的字段
                # 参考函数parse_list_page_common() 中 item_parser.get_common_raw_item()代码
                'tos': '国有产权',
                'tos_code': '05',
                'notice_type': '挂牌披露信息',
                'notice_type_code': '0501',
                'source': '北京公共资源交易网',
                'site_name': '北京公共资源交易网',
                'area_code': '11',
                'content_code': '1',
                'bid_sort': 'jyxxswzcgpplxx',
                'industryName': '',
                'time_type': 6 if self.crawl_mode == CrawlMode.HISTORY else 0,
            },

            'page_11': {
                # 通常会被填充在'source'字段里,有时也可以放在'tos'
                'name': '北京公共资源交易网',

                # list页面的base地址
                'base_url': 'https://ggzyfw.beijing.gov.cn/',

                # list页面的call_back处理函数
                'callback': self.parse_list_page_common,

                # 得到下一页url的函数,返回值一定是一个url
                'get_next_page_url': self.get_normal_next_page_url,

                # 网站中该页面的最大页数,(可选配置,仅为优化程序执行效率,可不填)
                'stop_page_num': 7000000,

                # 连续遇到[stop_dup_item_num]个重复条目后,停止本次抓取
                # 提示:在程序运行初始阶段,此值可以设的较大,以便爬取所有的历史记录
                'stop_dup_item_num': 500000 if self.crawl_mode == CrawlMode.HISTORY else 60,

                # list页面中,获得条目列表的xpath
                'xpath_of_list': '//ul[@class="article-list2"]/li',

                # 获得每一个条目链接地址的xpath
                'xpath_of_detail_url': './a/@href',

                # 对每一个条目进行解析,返回CommonRawItem的类,需要实现
                'item_parse_class': BaseItemCommonParser,

                # 其它信息,可以辅助生成CommonRawItem的字段
                # 参考函数parse_list_page_common() 中 item_parser.get_common_raw_item()代码
                'tos': '国有产权',
                'tos_code': '05',
                'notice_type': '交易结果',
                'notice_type_code': '0502',
                'source': '北京公共资源交易网',
                'site_name': '北京公共资源交易网',
                'area_code': '11',
                'content_code': '1',
                'bid_sort': 'jyxxswzcjyjg',
                'industryName': '',
                'time_type': 6 if self.crawl_mode == CrawlMode.HISTORY else 0,
            },

            'page_12': {
                # 通常会被填充在'source'字段里,有时也可以放在'tos'
                'name': '北京公共资源交易网',

                # list页面的base地址
                'base_url': 'https://ggzyfw.beijing.gov.cn/',

                # list页面的call_back处理函数
                'callback': self.parse_list_page_common,

                # 得到下一页url的函数,返回值一定是一个url
                'get_next_page_url': self.get_normal_next_page_url,

                # 网站中该页面的最大页数,(可选配置,仅为优化程序执行效率,可不填)
                'stop_page_num': 7000000,

                # 连续遇到[stop_dup_item_num]个重复条目后,停止本次抓取
                # 提示:在程序运行初始阶段,此值可以设的较大,以便爬取所有的历史记录
                'stop_dup_item_num': 500000 if self.crawl_mode == CrawlMode.HISTORY else 60,

                # list页面中,获得条目列表的xpath
                'xpath_of_list': '//ul[@class="article-list2"]/li',

                # 获得每一个条目链接地址的xpath
                'xpath_of_detail_url': './a/@href',

                # 对每一个条目进行解析,返回CommonRawItem的类,需要实现
                'item_parse_class': BaseItemCommonParser,

                # 其它信息,可以辅助生成CommonRawItem的字段
                # 参考函数parse_list_page_common() 中 item_parser.get_common_raw_item()代码
                'tos': '软件信息服务',
                'tos_code': '90',
                'notice_type': '招标公告',
                'notice_type_code': '9001',
                'source': '北京公共资源交易网',
                'site_name': '北京公共资源交易网',
                'area_code': '11',
                'content_code': '1',
                'bid_sort': 'jyxxrjxxzbgg',
                'industryName': '',
                'time_type': 6 if self.crawl_mode == CrawlMode.HISTORY else 0,
            },

            'page_13': {
                # 通常会被填充在'source'字段里,有时也可以放在'tos'
                'name': '北京公共资源交易网',

                # list页面的base地址
                'base_url': 'https://ggzyfw.beijing.gov.cn/',

                # list页面的call_back处理函数
                'callback': self.parse_list_page_common,

                # 得到下一页url的函数,返回值一定是一个url
                'get_next_page_url': self.get_normal_next_page_url,

                # 网站中该页面的最大页数,(可选配置,仅为优化程序执行效率,可不填)
                'stop_page_num': 7000000,

                # 连续遇到[stop_dup_item_num]个重复条目后,停止本次抓取
                # 提示:在程序运行初始阶段,此值可以设的较大,以便爬取所有的历史记录
                'stop_dup_item_num': 500000 if self.crawl_mode == CrawlMode.HISTORY else 60,

                # list页面中,获得条目列表的xpath
                'xpath_of_list': '//ul[@class="article-list2"]/li',

                # 获得每一个条目链接地址的xpath
                'xpath_of_detail_url': './a/@href',

                # 对每一个条目进行解析,返回CommonRawItem的类,需要实现
                'item_parse_class': BaseItemCommonParser,

                # 其它信息,可以辅助生成CommonRawItem的字段
                # 参考函数parse_list_page_common() 中 item_parser.get_common_raw_item()代码
                'tos': '软件信息服务',
                'tos_code': '90',
                'notice_type': '中标候选人公示',
                'notice_type_code': '9002',
                'source': '北京公共资源交易网',
                'site_name': '北京公共资源交易网',
                'area_code': '11',
                'content_code': '1',
                'bid_sort': 'jyxxrjxxzbhx',
                'industryName': '',
                'time_type': 6 if self.crawl_mode == CrawlMode.HISTORY else 0,
            },

            'page_14': {
                # 通常会被填充在'source'字段里,有时也可以放在'tos'
                'name': '北京公共资源交易网',

                # list页面的base地址
                'base_url': 'https://ggzyfw.beijing.gov.cn/',

                # list页面的call_back处理函数
                'callback': self.parse_list_page_common,

                # 得到下一页url的函数,返回值一定是一个url
                'get_next_page_url': self.get_normal_next_page_url,

                # 网站中该页面的最大页数,(可选配置,仅为优化程序执行效率,可不填)
                'stop_page_num': 7000000,

                # 连续遇到[stop_dup_item_num]个重复条目后,停止本次抓取
                # 提示:在程序运行初始阶段,此值可以设的较大,以便爬取所有的历史记录
                'stop_dup_item_num': 500000 if self.crawl_mode == CrawlMode.HISTORY else 60,

                # list页面中,获得条目列表的xpath
                'xpath_of_list': '//ul[@class="article-list2"]/li',

                # 获得每一个条目链接地址的xpath
                'xpath_of_detail_url': './a/@href',

                # 对每一个条目进行解析,返回CommonRawItem的类,需要实现
                'item_parse_class': BaseItemCommonParser,

                # 其它信息,可以辅助生成CommonRawItem的字段
                # 参考函数parse_list_page_common() 中 item_parser.get_common_raw_item()代码
                'tos': '软件信息服务',
                'tos_code': '90',
                'notice_type': '中标结果',
                'notice_type_code': '9002',
                'source': '北京公共资源交易网',
                'site_name': '北京公共资源交易网',
                'area_code': '11',
                'content_code': '1',
                'bid_sort': 'jyxxrjxxjyjg',
                'industryName': '',
                'time_type': 6 if self.crawl_mode == CrawlMode.HISTORY else 0,
            },

        }

        logging.info('start crawling...')

        # 轮询每个类别
        for _k, _v in _source_info.items():

            # 仅爬取指定类型
            if 'type' in self.__dict__ and self.type != _k:
                continue

            # 填充爬取的基本信息
            self.crawl_helper.init_crawl_info(_k, _v)

            # 假定每个类别有不超过100000个页面
            for _page_num in range(1000000):
                # 如果有start_page项,忽略之前的页面
                if 'start_page' in self.__dict__ and _page_num < int(self.start_page) - 1:
                    continue

                # 如果有end_page项
                if 'end_page' in self.__dict__ and _page_num > int(self.end_page) + 1:
                    break

                # 轮询公告中的不同list页面
                if self.crawl_helper.get_stop_flag(_k):
                    break

                # 根据获得下一页的函数,得到下一页的URL
                _ext_param = {
                    'time_type': _v['time_type'],
                    'bid_sort': _v['bid_sort'],
                    'start_time': self.start_time,
                    'end_time': self.end_time,
                }
                _request_url = _v['get_next_page_url'](page_index=_page_num, base_url=_v['base_url'],
                                                       ext_param=_ext_param)

                # 生成request
                _request = scrapy.Request(_request_url, callback=_v['callback'])
                # 使用proxy
                _request.meta['proxy'] = JyScrapyUtil.get_http_proxy()
                _request.meta['max_retry_times'] = 5
                logging.info('Use proxy[] to generate scrapy request'.format(_request.meta['proxy']))
                # 如果需要js渲染,需要使用下面的函数
                # _request = SplashRequest(_request_url, callback=_v['callback'], args={'wait': 2})

                # 填充必要的参数
                _request.meta['param'] = _v
                _request.meta['crawl_key'] = _k
                _request.meta['page_index'] = _page_num + 1

                yield _request

            # 单个类别的爬取结束
            self.crawl_helper.stop_crawl_info(_k)

        logging.info('stop crawling...')
    def start_requests(self):
        """
        爬虫默认接口,启动方法
        :return:
        """
        # 获取爬取时传过来的参数
        # start_time: 开始时间
        # end_time: 结束时间
        # start_page: 开始页 (优先于start_time)
        # end_page: 结束页 (优先于end_time)
        # stop_item: 连续遇到[stop_item]个重复条目后,退出本次爬取
        # spider_name: 指定的spider_name,如果不指定,使用self.name
        # command example:
        # py -3 -m scrapy crawl base_spider -a start_time="2019:01:01" -a end_time="2019:01:02"
        # py -3 -m scrapy crawl base_spider -a start_time="now" -a end_time="now"
        # python3 -m scrapy crawl southern_power_spider -a start_time="now" -a end_time="now"
        # py -3 -m scrapy crawl base_spider -a start_time="now" -a end_time="now" -a start_page="700" -a end_page="1000" -a stop_item="10000"
        assert self.start_time is not None
        assert self.end_time is not None

        self.crawl_mode = CrawlMode.REAL_TIME if str(self.start_time).lower() == 'now' else CrawlMode.HISTORY

        if self.crawl_mode == CrawlMode.HISTORY:
            if (len(self.start_time) != 10 or len(self.end_time) != 10
                    or self.start_time[4] != ':' or self.end_time[4] != ':'):
                logging.error('Bad date format start_time:[{}] end_time:[{}]. Example: 2019:01:01'.format(
                    self.start_time, self.end_time))
                return
        else:
            # 取当天日期
            _dt = datetime.fromtimestamp(time.time())
            self.start_time = _dt.strftime("%Y:%m:%d")
            self.end_time = self.start_time

        # 初始化self.crawl_helper
        self.init_crawl_helper()

        # 主要配置项
        _source_info = {
            # 页面的key,保证唯一
            'zbgg_search': {
                # 通常会被填充在'source'字段里,有时也可以放在'tos'
                'name': '南方电网招标',

                # list页面的base地址
                'base_url': 'http://www.bidding.csg.cn/zbgg/',

                # list页面的call_back处理函数
                'callback': self.parse_list_page_common,

                # 得到下一页url的函数,返回值一定是一个url
                'get_next_page_url': self.get_normal_next_page_url,

                # 网站中该页面的最大页数,(可选配置,仅为优化程序执行效率,可不填)
                'stop_page_num': 7000000,

                # 连续遇到[stop_dup_item_num]个重复条目后,停止本次抓取
                # 提示:在程序运行初始阶段,此值可以设的较大,以便爬取所有的历史记录
                'stop_dup_item_num': 500000 if self.crawl_mode == CrawlMode.HISTORY else 60,

                # list页面中,获得条目列表的xpath
                # 'xpath_of_list': '//ul[@class="vT-srch-result-list-bid"]/li',
                'xpath_of_list': '//div[@class="BorderEEE NoBorderTop List1 Black14 Padding5"]/li',

                # 获得每一个条目链接地址的xpath
                'xpath_of_detail_url': './a/@href',

                # 对每一个条目进行解析,返回CommonRawItem的类,需要实现
                'item_parse_class': BaseItemCommonParser,

                # 其它信息,可以辅助生成CommonRawItem的字段
                # 参考函数parse_list_page_common() 中 item_parser.get_common_raw_item()代码
                'tos': '企业采购',
                'source': '招标公告',
                # 'bid_sort': 1,
                'time_type': 6 if self.crawl_mode == CrawlMode.HISTORY else 0,
            },


        }

        logging.info('start crawling...')

        # 轮询每个类别
        for _k, _v in _source_info.items():

            # 仅爬取指定类型
            if 'type' in self.__dict__ and self.type != _k:
                continue

            # 填充爬取的基本信息
            print(_k)
            print(_v)


            self.crawl_helper.init_crawl_info(_k, _v)


            # 假定每个类别有不超过100000个页面
            for _page_num in range(1000000):
                # 如果有start_page项,忽略之前的页面
                if 'start_page' in self.__dict__ and _page_num < int(self.start_page) - 1:
                    continue

                # 如果有end_page项
                if 'end_page' in self.__dict__ and _page_num > int(self.end_page) + 1:
                    break

                # 轮询公告中的不同list页面
                if self.crawl_helper.get_stop_flag(_k):
                    break

                # 根据获得下一页的函数,得到下一页的URL
                _ext_param = {
                    'time_type': _v['time_type'],
                    # 'bid_sort': _v['bid_sort'],
                    'start_time': self.start_time,
                    'end_time': self.end_time,
                }
                _request_url = _v['get_next_page_url'](page_index=_page_num, base_url=_v['base_url'], ext_param=_ext_param)

                # 生成request
                _request = scrapy.Request(_request_url, callback=_v['callback'])
                # 使用proxy
                _request.meta['proxy'] = JyScrapyUtil.get_http_proxy()
                _request.meta['max_retry_times'] = 5
                logging.info('Use proxy[] to generate scrapy request'.format(_request.meta['proxy']))
                # 如果需要js渲染,需要使用下面的函数
                # _request = SplashRequest(_request_url, callback=_v['callback'], args={'wait': 2})

                # 填充必要的参数
                _request.meta['param'] = _v
                _request.meta['crawl_key'] = _k
                _request.meta['page_index'] = _page_num + 1

                yield _request

            # 单个类别的爬取结束
            self.crawl_helper.stop_crawl_info(_k)

        logging.info('stop crawling...')