![]() |
![]() |
很重要--轉載聲明
- 本站文章無特別說明,皆爲原創,版權全部,轉載時請用連接的方式,給出原文出處。同時寫上原做者:朝十晚八 or Twowords
- 如要轉載,請原文轉載,如在轉載時修改本文,請事先告知,謝絕在轉載時經過修改本文達到有利於轉載者的目的。
學習python有一段時間了,最近了解了下Python的入門爬蟲框架Scrapy,參考了文章Python爬蟲框架Scrapy入門。本篇文章屬於初學經驗記錄,比較簡單,適合剛學習爬蟲的小夥伴。
此次我選擇爬取boss直聘的招聘信息數據,畢竟這個網站的數據仍是頗有參考價值的,下面咱們講述怎麼爬取boss直聘的招聘信息並存盤,下一篇文章咱們在對爬取到的數據進行分析。css
下面咱們作一個簡單示例,建立一個名字爲BOSS的爬蟲工程,而後建立一個名字爲zhipin的爬蟲來爬取zhipin.com這個網站html
建立工程步驟:python
一、建立工程 scrapy startproject BOSSmongodb
二、建立爬蟲程序 cd BOSS 回車 scrapy gensipder zhipin zhipin.com數據庫
三、編寫數據存儲模板items.py 類對象繼承自scrapy.itempython爬蟲
四、編寫爬蟲zhipin.py 類對象集成子scrapy.Spider框架
五、修改settings.py配置文件 ITEM_PIPELINES = {'BOSS.pipelines.WwwZhipinComPipeline':100}dom
六、編寫數據處理腳本進行數據保存,pipelines.py 類對象繼承自objectscrapy
1 def process_item(self, item, spider): 2 with open("my_boss.txt", 'a') as fp: 3 fp.write(item['name'] + '\n')
七、執行爬蟲 cd BOSS 回車 scrapy crawl zhipin --nologide
注意:若是導出的中文信息亂碼則須要在settings.py文件中配置編碼:FEED_EXPORT_ENCODING = 'utf-8'
爬蟲框架咱們使用Scrapy,爬取到的數據咱們使用mongodb來存儲
一、安裝Scrapy
1 pip install Scrapy
二、安裝mongodb
1 pip install pymongo
若是安裝速度太慢,或者安裝失敗能夠嘗試使用pip install pymongo -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
mongodb基礎操做命令參考:MongoDB基本命令操做
上述操做只是安裝了mongodb的python驅動程序,若是要成功存儲數據還須要安裝Mongodb,具體安裝流程參考Windows平臺安裝MongoDB,安裝完成後必定要記得使用命令啓動mongodb服務:net start MongoDB
上一小節咱們已經安裝了mongodb數據庫和驅動,所以後續咱們爬取到的招聘信息就存儲在該數據庫中,爲了方便數據存儲,咱們這裏封裝了一個類,來快速的訪問數據庫,代碼以下所示
1 from pymongo import MongoClient 2 3 class my_connect(object): 4 def __init__(self, settings): 5 try: 6 self.conn = MongoClient(settings["ip"], settings["port"]) 7 except Exception as e: 8 print(e) 9 self.db = self.conn[settings["db_name"]] 10 self.my_set = self.db[settings["set_name"]] 11 12 def insert(self, dic): 13 self.my_set.insert(dic) 14 15 def update(self, dic, newdic): 16 self.my_set.update(dic, newdic) 17 18 def delete(self, dic): 19 self.my_set.remove(dic) 20 21 def dbfind(self, dic): 22 return self.my_set.find(dic) 23 24 def setTableName(self, name): 25 #print(u'修改當前使用集合:{}'.format(name)) 26 self.my_set = self.db[name]
上述代碼中咱們封裝了一個名爲my_connect的類,並提供了輸入、更新、刪除和查找文檔的接口,除此以外還提供了一個setTableName的接口,這個接口主要是用於往不一樣集合中插入文檔數據。MongoDB 概念解析能夠看這裏。mongodb屬於非關係型數據庫,與關係型數據庫對比圖以下
my_connect初始化函數中有一個參數,須要咱們傳入ip地址、端口號、數據庫名字和集合名字,使用方式以下所示
1 from pymongo import MongoClient 2 from my_connect import my_connect 3 4 settings = { 5 "ip":'127.0.0.1', #ip 6 "port":27017, #端口 7 "db_name" : "zhipin_datas", #數據庫名字 8 "set_name" : "test" #集合名字 9 } 10 11 conn = my_connect(settings) 12 conn.setTableName('21') 13 conn.insert({'12':'3'})
一、輸入以下命令,建立zhipin爬蟲
1 scrapy startproject www_zhipin_com 2 cd www_zhipin_com 回車 scrapy gensipder zhipin www.zhipin.com
二、修改zhipin.py,爬取數據,類中成員屬性含義代碼中都有解釋,這裏不作解釋,須要注意的是parse方法,該方法是爬取到數據之後的回調函數,參數response表示爬取到的結果,咱們能夠對其進行解析拿到網頁數據。
1 class ZhipinSpider(scrapy.Spider): 2 # spider的名字定義了Scrapy如何定位(並初始化)spider,因此其必須是惟一的。 3 # 不過您能夠生成多個相同的spider實例(instance),這沒有任何限制。 4 # name是spider最重要的屬性,並且是必須的 5 name = 'zhipin' 6 7 # 可選。包含了spider容許爬取的域名(domain)列表(list)。 8 # 當 OffsiteMiddleware 啓用時, 域名不在列表中的URL不會被跟進。 9 allowed_domains = ['www.zhipin.com'] 10 11 # URL列表。當沒有指定特定的URL時,spider將從該列表中開始進行爬取。 12 # 這裏咱們進行了指定,因此不是從這個 URL 列表裏爬取 13 start_urls = ['http://www.zhipin.com/'] 14 15 #網址URL中特殊字符轉義編碼:https://blog.csdn.net/u010828718/article/details/50548687 16 #爬取的頁面,能夠改成本身須要搜的條件,這裏搜的是 北京-C++,其餘條件都是不限 17 #query:查詢崗位 18 #period:時間範圍 5表示一個月內 &在url中須要寫爲%26 19 #a_街道b_區名稱 eg:a_上地-b_海淀區 包含在路徑內,城市編號(c101010100)下一級 20 positionUrl = 'https://www.zhipin.com/c101010100/?query=C%2B%2B%' 21 curPage = 1
解析數據時,默認一次能夠拿到30條數據,咱們循環遍歷這30條數據,構造WwwZhipinComItem對象item,而後調用yield item便可
1 def parse(self, response): 2 job_list = response.css('div.job-list > ul > li') 3 request_data = [] 4 for job in job_list: 5 item = WwwZhipinComItem() 6 ... 7 yield item
2.一、這裏有一個小技巧,咱們重寫start_requests方法,讓他調用了咱們本身寫的一個方法next_request,並設置了回調函數爲parse方法,當parse數據解析完畢後,又構造一個新的url在次調用next_request方法拉取數據,一直循環迭代,拉取數據、解析數據
2.二、boss直聘有一個限制,無論以什麼樣的方式搜索數據,數據最多顯示10頁,這也就要求咱們須要對爬蟲作一個處理,在合適的實際去終止拉取數據,不然爬蟲會一直運行下去,直到boss直聘返回異常(請求被限制)
2.三、通過對爬蟲數據的分析,咱們發現當最後一次請求和上一次請求的數據徹底同樣時,咱們可能已經到達請求的最後一頁,那麼這個時候咱們就能夠去終止爬蟲了
2.四、爲了快速的比對我麼爬取到的數據是否和上一次同樣,咱們對爬取到的數據進行簡單的處理,每次去對比關鍵字段便可
1 class itemData(object): 2 def __init__(self, data): 3 self.companyShortName = data['companyShortName'] 4 self.positionName = data['positionName'] 5 self.time = data['time'] 6 self.city = data['city'] 7 8 def __eq__(self, other): 9 return (self.positionName == other.positionName 10 and self.companyShortName == other.companyShortName 11 and self.time == other.time 12 and self.city == other.city) 13 14 def __str__(self): 15 return "{}:{}:{}:{}".format(self.companyShortName 16 , self.time 17 , self.city 18 , self.positionName)
itemData包含是一條招聘信息,存儲了招聘公司名稱,職位名稱,發佈時間和發佈城市,咱們重寫了__eq__方法,就是爲了比對兩個對象是否相等。
2.五、一次請求的數據是一個itemData集合,當兩個集合相等時咱們便可終止爬蟲
1 if one_request == request_data:#已經拉取到最後一頁數據了 退出 2 print('{}:本次拉取數據和上次拉取數據相同,{}'.format(time.strftime("%Y-%m-%d %H:%M:%S" 3 , time.localtime()), self.curPage)) 4 return 5 6 one_request = request_data #更新最後一次請求數據 7 8 print('{}:拉取數據量:{}'.format(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), len(job_list))) 9 self.curPage += 1 10 time.sleep(5) # 停停停!聽聽聽!都給我停下來聽着!睡一會(~﹃~)~zZ 11 yield self.next_request()
2.六、parse解析數據時,對每一條數據會構造一個WwwZhipinComItem對象item,並經過yield item方式觸發
三、對於爬取的字段定義須要咱們修改item.py文件,定義爬取字段以下
1 class WwwZhipinComItem(scrapy.Item): 2 # define the fields for your item here like: 3 # name = scrapy.Field() 4 pid = scrapy.Field() 5 positionName = scrapy.Field() 6 positionLables = scrapy.Field() 7 workYear = scrapy.Field() 8 salary = scrapy.Field() 9 city = scrapy.Field() 10 education = scrapy.Field() 11 companyShortName = scrapy.Field() 12 industryField = scrapy.Field() 13 financeStage = scrapy.Field() 14 companySize = scrapy.Field() 15 time = scrapy.Field() 16 updated_at = scrapy.Field()
四、最後一步寫入數據庫
4.一、第四節咱們封裝了一個名字爲my_connect的數據庫操做對象,在這裏咱們就能夠用上了。
4.二、首先構造一個conn對象
1 db_name = 'zhipin_datas_C++' 2 nowMonth = datetime.datetime.now().month 3 settings = { 4 "ip":'127.0.0.1', #ip 5 "port":27017, #端口 6 "db_name" : db_name, #數據庫名字 7 "set_name" : "test" #集合名字 8 } 9 10 conn = my_connect(settings)
4.三、指定要插入的集合,而後構造數據、插入數據
1 conn.setTableName(month) 2 3 data = {"pid": item['pid']#"27102804" 4 , "positionName": item['positionName'] 5 , "positionLables": item['positionLables']#[] 6 , "workYear": item['workYear']#"5-10年" 7 , "salary": item['salary']#"30k-50k" 8 , "city": item['city']#"北京 海淀區 知春路" 9 , "education": item['education']#"碩士" 10 , "companyShortName": item['companyShortName']#"vmware" 11 , "industryField": item['industryField']#"計算機軟件" 12 , "financeStage": item['financeStage']#"已上市" 13 , "companySize": item['companySize']#"10000人以上" 14 , "time": item['time']#"2018-11-13 17:35:02" 15 , "updated_at": item['updated_at']#"2018-11-13 17:35:02" 16 } 17 18 conn.insert(data)
4.四、數據爬取結束後,使用gui工具Navicat 12 for MongoDB能夠查看爬取到的數據,效果以下圖所示
須要所有代碼的到csdn直接下載:python爬蟲Scrapy(一)-我爬了boss數據