使用scrapy抓取目標url下所有的課程名和價格,並將數據保存為json格式url=http://www.tanzhouedu.com/mall/course/initAllCourse
觀察網頁並分析該網頁:
是一個ajax加載的頁面,每次數據變化,但是url不變化,
通過查看headers中的信息,得到每次點擊下一頁時真正請求的鏈接url
觀察發現每次翻頁,請求變化的是offset的數值和時間戳
1.創建項目
使用命令:scrapy startproject 'project_name'得到對象的項目文件夾,里面包含scrapy的一些必要組件
如下:

具體文件含義,參見鏈接:http://www.cnblogs.com/pythoner6833/p/9012292.html
2.明確抓取目標。
編輯items.py文件,定義好需要抓取的數據字段名
代碼如下:
# -*- coding: utf-8 -*- # Define here the models for your scraped items # # See documentation in: # https://doc.scrapy.org/en/latest/topics/items.html import scrapy class TanzhouItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() """ 定義爬取的目標,本案例中只爬取標題和價格兩個內容 所以定義兩個字段 """ # 課程金額 money = scrapy.Field() # 課程名稱 title = scrapy.Field()
3.編輯爬蟲。
進入spiders文件夾下,創建爬蟲文件,命令:scrapy genspider 'spider_name' "start_url"
就會得到一個以spider_name命名的文件,在里面編寫爬蟲的邏輯
# -*- coding: utf-8 -*- """ 抓取:http://www.tanzhouedu.com/mall/course/initAllCourse 下的所有課程名稱和價格,並保存為json格式 網頁分析: 是一個ajax加載的頁面,每次數據變化,但是url不變化, 通過查看headers中的信息,得到每次點擊下一頁時真正請求的鏈接url 觀察發現每次翻頁,請求變化的是offset的數值和時間戳 1.首先創建一個爬蟲項目。 使用命令:scrapy startproject 'pro_name' # pro_name是項目名稱 輸入命令后,會自動出現一個用pro_name的項目文件夾, 里面包含一個scrapy項目所必要的文件 2.明確爬取目標,編輯items.py文件,定義需要爬取的字段。 3.編輯爬蟲。進入spiders文件夾下,創建爬蟲文件。 使用命令:scrapy genspider 'spider_name' 'start_url' 生成一個爬蟲,名字為spider_name,初始爬取url為start_url 會在spiders文件夾下生成一個spider_name.py的文件, 里面包含一個name=‘spider_name’, name是不同爬蟲的唯一標識,不能重復 start_url是爬蟲的第一個爬取鏈接(可修改),並返回一個response 解析response中的其他可用鏈接和數據 4.將爬取到的數據通過yield,丟給pipelines.py文件保存, 在pipelines.py文件中編寫保存文件的邏輯 5.運行爬蟲,使用命令:scrapy crawl "spider_name" 注:在配置文件中打開頭信息和管道 """ import scrapy # 從items文件中導入已經寫好的待爬取目標(money和title) from tanzhou.items import TanzhouItem import time class TzSpider(scrapy.Spider): name = 'tz' # 爬蟲名稱。區別於其他爬蟲的唯一ID。 allowed_domains = ['tanzhouedu.com'] # 允許域名 # 爬蟲的第一個爬取鏈接,啟動爬蟲就執行,並返回一個response交給parse函數 start_urls = ['http://www.tanzhouedu.com/mall/course/initAllCourse'] offset = 0 def parse(self, response): item = TanzhouItem() # 實例化。實例一個爬取字段的實例對象。 # 通過xpath解析response,並從中提取數據,得到xpath對象 node_list = response.xpath('//div[@id="newCourse"]/div/div/ul/li') for node in node_list: # extract_first() 是取對象的值,得到一個字符串 item['money'] = node.xpath('./div/span/text()').extract_first() item['title'] = node.xpath('./a/@title').extract_first() yield item # yield將item返回,scrapy_engine通過管道,將item交給pipelines # pipelines.py文件用於爬取結果的保存 if node_list == []: """ 下一頁到最后時,xpath匹配到的是一個空列表 此時已沒有可爬取頁面,return結束程序。 """ return self.offset += 20 # 構造變化的offset,每次翻頁增加20 # yield將新的請求丟給調度器,然后交給下載器,繼續下載頁面,得到response # callback回調parse函數,實現循環抓取 yield scrapy.Request(url="http://www.tanzhouedu.com/mall/course/initAllCourse?params.offset=" + str(self.offset) +"¶ms.num=20&keyword=&_=" + str(int(time.time() * 1000)), callback=self.parse)
4.編寫保存數據的邏輯。
在pipelines.py文件中編寫保存數據的邏輯
# -*- coding: utf-8 -*- # Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html import json class TanzhouPipeline(object): """ 編寫爬取到的數據保存的邏輯 """ def __init__(self): """ 可選擇實現,對參數做一些初始化的處理 """ pass def open_spider(self, spider): """ 重寫open_spider函數,該函數在爬蟲啟動時就自動執行 :param spider: :return: """ self.file = open("tz.json", 'w', encoding='utf-8') def process_item(self, item, spider): """ 將yield丟過來的數據進行一定的處理並保存 :param item: :param spider: :return: """ # 管道傳過來的數據item是一個對象,將它轉化為字典,然后存儲 content = json.dumps(dict(item), ensure_ascii=False) + '\n' self.file.write(content) return item def close_spider(self, spider): """ 重寫該函數,爬蟲執行完畢后執行該函數 :param spider: :return: """ self.file.close()
5.運行爬蟲。
使用命令:scrapy crawl "spider_name"
運行結果:

得到一個保存有抓取結果的json文件

