csdn上已經有很多的關於CrawlSpider框架的講解,以及其主要的使用方法,其整體的數據流向和Spider框架的數據流向是大體一樣的,因爲CrawlSpider是繼承自Spider的類,Spider框架的介紹我在之前的博文中寫過,
CrawlSpider框架的介紹我之後也想寫一篇博文來加深自己的理解,這裏通過實戰來對其整體流程進行理解(半通用化)。
CrawlSpider半通用化抓站
1. 新建Scrapy項目
scrapy startproject rent_lianjia
2. 創建一個CrawlSpider
使用pycharm打開剛纔創建的Scrapy項目,在Terminal中輸入創建的命令:
scrapy genspider -t crawl lianjia
3. 分析目標網頁
3.1 目標網址
該地址是鏈家網的定位西安的租房信息的URL:
start_urls = ['https://xa.lianjia.com/zufang/']
# 或
#start_urls = ['https://xa.lianjia.com/zufang/pg1/#contentList']
3.2 明確爬蟲的目的和步驟思路
- 獲取網頁中每一個房子的跳轉鏈接
- 通過鏈接分別進入其具體的租房信息網頁
- 爬取你想獲取的房子的相關信息
3.3 分析目標網頁
該網頁是針對西安租房的:
3.3.1 查看網頁源碼,找尋房子的跳轉鏈接
可以很簡單的找到每個房子的跳轉鏈接存放在a標籤當中的href屬性當中,恆容易用xpath提取
3.3.2 查看網頁源碼,找尋頁面的跳轉鏈接(兩種方法)
3.3.2.1 方法一(直接編寫rule):
可以看到其網頁的跳轉鏈接都保存在ul的列表裏
rules = (
Rule(LinkExtractor(restrict_xpaths='//p[@class="content__list--item--title twoline"]//a'), callback='parse_item'),
Rule(LinkExtractor(restrict_xpaths='//ul[@style="display:hidden"]//a'))
)
查看後臺請求的結果:
按道理來說這樣是可以完成所有的網頁鏈接的請求。關於rule的使用方法我會整理成一篇博文來加深自己的印象的,目前csdn上已經有很多相關的文章來介紹。
3.3.2.1 方法二(重寫parse_start_url方法):
這種方法是百度查看了crawlspider的源碼後,也有人這樣實現過自己也想嘗試以下:
Scrapy框架CrawlSpiders的介紹以及使用
這個裏面介紹了其源碼,是如何對url鏈接進行請求操作的,都使用了什麼方法,我感覺對於小白的我來說很好。
自己的嘗試:
def parse_start_url(self, response):
for i in range(1,10):
url = 'https://xa.lianjia.com/zufang/pg' + str(i+1) + '/#contentList'
yield scrapy.Request(url)
解釋以下 parse_start_url 方法:
它是一個可以重寫的方法。當start_urls裏對應的Request得到Response時,這個方法會被調用,它會分析Response並返回Item對象或者Request對象。
自己的事件證明方法是可以的,後臺的請求結果:
4. 編寫相應的Item和實現相應的爬取方法
class HouseItem(Item):
# define the fields for your item here like:
# name = scrapy.Field()
price = Field()
rentWay = Field()
size = Field()
floor = Field()
url = Field()
name = Field()
4.1 幾個xpath提取自己認爲實用的方法
def parse_item(self, response):
item = HouseItem()
item['name'] = response.xpath('//p[@class="content__title"]/text()').extract_first()
item['price'] = ''.join(response.xpath('//div[@class="content__aside--title"]/span/text()').extract_first()) + ''.join(response.xpath('//div[@class="content__aside--title"]/text()').extract()).strip()
item['rentWay'] = ''.join(response.xpath('//ul[@class="content__aside__list"]//text()').extract()).strip().split('\n')[0]
item['size'] = ''.join(response.xpath('//ul[@class="content__aside__list"]//text()').extract()).strip().split('\n')[1]
item['floor'] = ''.join(response.xpath('//ul[@class="content__aside__list"]//text()').extract()).strip().split('\n')[2]
item['url'] = response.url
#item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get()
#item['name'] = response.xpath('//div[@id="name"]').get()
#item['description'] = response.xpath('//div[@id="description"]').get()
return item
在進行xpath提取的時候,由於框架顯示不方便,自己的做法是每次另寫一個.py文件,專門對數據進行xpth的編寫,調試數據的返回結果和格式,帶正確以後再放入框架當中。在使用xpath的時候,用strip()能處理大部分的網頁中的空格或者換行,但還得進行一定的分割和拼接,用split()方法,自己得琢磨 “/”和“//”的區別所在,一個是返回直接子節點的信息,一個是返回所有子幾點的信息,二者有很大的不同,得在不斷的練習當中發現其中的用法。
5. 後臺粗暴顯示數據
6. 該代碼存在的問題,望大佬指點
- 自己也在琢磨這個crawlspider,上述有問題的請大家諒解及時評論或私信指出,我立馬修改。
- 當響應的網頁變多,網站的服務器會識別是否是人爲操作,在後面的返回的網頁請求中會打不開,是人機識別的界面,無法獲取信息,有什麼好的方法或者號的博文鏈接可以私信或評論,帶帶小弟我。
- 自己知道的簡單的方法有直接粗暴的sleep等待,每次請求完就等待,更換請求的IP地址,有沒有好 的免費的ip地址網站提供推薦,多幾個請求的頭,模擬不同的瀏覽器。
- 總的來說就是如何更好的去請求網頁,讓服務器不容易發現,當大規模爬取數據的時候,望大佬指點。