scrapy爬虫框架简单入门实例(二)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010815486/article/details/83786152

接着上一篇文章,我们已经可以用爬虫访问目标网站爬取页面了,现在需要自动提交表单查询数据,并且从页面中筛选出每期中奖号码保存为json文件导出。首先创建一个scrapy.Item类(打开项目文件夹下的items.py文件):

import scrapy


class SsqSpiderItem(scrapy.Item):
    issue_num = scrapy.Field()
    red = scrapy.Field()
    blue = scrapy.Field()

我们需要爬取每期中奖号码的期数,以及红球数组和蓝球号;定义属性值为scrapy.Field()。然后回到爬虫代码引入这个类:

from ssq_spider.items import SsqSpiderItem

直接贴一个写好的代码:

# -*- coding: utf-8 -*-
import scrapy
from scrapy.http import Request, FormRequest
from ssq_spider.items import SsqSpiderItem


class SsqSpider(scrapy.Spider):
    name = 'ssq'
    allowed_domains = ['http://zst.aicai.com/ssq/']  # 爬取域名
    # start_urls = ['http://zst.aicai.com/ssq/']
    # 爬取网址,只适于不需要提交cookie的网站,因为没法设置cookie等信息
    scope_date = [['2012001', '2014200'], [
        '2015001', '2017200'], ['2018001', '2018130']]

    # 设置浏览器用户代理
    header = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0'}

    def start_requests(self):
        # 第一次请求页面,设置开启cookie使其得到cookie,设置回调函数
        return [Request('http://zst.aicai.com/ssq/', meta={'cookiejar': 1}, callback=self.parse)]

    def parse(self, response):
        print('请求头信息')
        print(response.request.headers)
        print('响应头信息')
        print(response.headers)
        print(response.status)
        print('---Cookie---')
        # 请求Cookie
        request_Cookie = response.request.headers.getlist('Cookie')
        print(request_Cookie)
        # 响应Cookie
        response_Cookie = response.headers.getlist('Set-Cookie')
        print(response_Cookie)
        print('---end---')
        # 设置提交表单信息,对应抓包得到字段
        for i in SsqSpider.scope_date:
            form_data = {
                'startIssue': i[0],
                'endIssue': i[1],
                'sIssue': '',
                'eIssue': '',
                'maxsize': '30',
                'openDate': '',
                'statisticsTag': '1',
                'sortTag': 'up'
            }
            # 第二次用表单post请求,携带Cookie、浏览器代理等信息给Cookie授权
            yield FormRequest.from_response(response,
                                            url='http://zst.aicai.com/ssq/',  # 真实post地址
                                            meta={'cookiejar': response.meta[
                                                'cookiejar']},
                                            headers=self.header,
                                            formdata=form_data,
                                            callback=self.next,
                                            dont_filter=True
                                            )

    def next(self, response):
        items = SsqSpiderItem()
        print(response.css('title').extract())
        html_tr = response.css('#tdata tr:not(.tdbck)')
        for i in html_tr:
            items['issue_num'] = i.css('td:nth-child(1)::text').extract()[0]
            items['red'] = i.css('.chartBall01::text').extract()
            items['blue'] = i.css('.chartBall02::text').extract()[0]
            yield items

从response对象中用scrapy自带的css选择器解析提取出数据,运行命令就可以导出json文件:

scrapy crawl '爬虫名称' -o items.json

或者通过配置pipelines导出json文件,打开pipelines.py:

import codecs
import os
import json


class JsonPipeline(object):
    def process_item(self, item, spider):
        base_dir = os.getcwd()
        filename = base_dir + '/ssq_item.json'
        # 打开json文件,以dumps的方式将一个Python数据类型列表进行json格式的编码
        # 注意需要有一个参数ensure_ascii=False ,不然数据会直接为utf编码的方式存入
        with codecs.open(filename, 'a') as f:
            line = json.dumps(dict(item), ensure_ascii=False) + ',\n'
            f.write(line)
        return item

接着编写settings.py ,我们需要在Settings.py将我们写好的pipeline添加进去,这里只需要增加一个dict格式ITEM_PIPELINES,数字value可以自定义,数字越小的优先处理。

ITEM_PIPELINES = {
    'ssq_spider.pipelines.JsonPipeline': 300,
}

运行爬虫就能导出json:

scrapy crawl '爬虫名称'

需要注意的是,这样导出的json文件格式不太严谨(缺少[ ]字符,程序直接读取json文件会报错);由于scrapy框架为了运行更有效率,采用的是多线程并行爬取,所以爬取的数据没有顺序:

强迫症表示不能忍,新建一个python文件用来排序:

import json


def sorting_json():
    with open('./spiders/ssq_item.json', 'r', encoding='utf-8') as s_i:
        json_data = json.load(s_i, strict=False)
        # 利用issue_num字段排序
        json_data.sort(key=lambda x: x['issue_num'], reverse=True)
        return json_data

with open('ssq.js', 'a') as s:
    n = sorting_json()
    for i, value in enumerate(n):
        if i == 0:
            s.write('var ssq_data = [')
        line = json.dumps(dict(value), ensure_ascii=False) + ',\n'
        if i == len(n) - 1:
            line = json.dumps(dict(value), ensure_ascii=False) + ']'
        s.write(line)

有了数据,就可以为所欲为了(邪魅一笑~):

随便用js写了个代码,想看看从2012年到现在有没有2期6个红球完全相同的情况,可惜没有;5个红球相同倒是有,而且13年有相邻的两期5个红球和蓝球号都一样。(被安排的明明白白……)

感慨一下,写爬虫其实不难,难的是反爬处理,这里推荐一个链接:https://weibo.com/ttarticle/p/show?id=2309404125351516226870

猜你喜欢

转载自blog.csdn.net/u010815486/article/details/83786152
今日推荐