scrapy爬蟲框架簡單入門例項(二)
阿新 • • 發佈:2018-11-27
接著上一篇文章,我們已經可以用爬蟲訪問目標網站爬取頁面了,現在需要自動提交表單查詢資料,並且從頁面中篩選出每期中獎號碼儲存為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