1. 程式人生 > >python爬蟲Scrapy(一)-我爬了boss資料 MongoDB基本命令操作

python爬蟲Scrapy(一)-我爬了boss資料 MongoDB基本命令操作

一、概述

    學習python有一段時間了,最近了解了下Python的入門爬蟲框架Scrapy,參考了文章Python爬蟲框架Scrapy入門。本篇文章屬於初學經驗記錄,比較簡單,適合剛學習爬蟲的小夥伴。
    這次我選擇爬取的是boss直聘來資料,畢竟這個網站的資料還是很有參考價值的,下面我們講述怎麼爬取boss直聘的招聘資訊並存盤,下一篇文章我們在對爬取到的資料進行分析。

二、Scrapy框架使用步驟

    下面我們做一個簡單示例,建立一個名字為BOSS的爬蟲工程,然後建立一個名字為zhipin的爬蟲來爬取zhipin.com這個網站

建立工程步驟:

1、建立工程 scrapy startproject BOSS

2、建立爬蟲程式 cd BOSS 回車 scrapy gensipder zhipin zhipin.com

3、編寫資料儲存模板items.py 類物件繼承自scrapy.item

4、編寫爬蟲zhipin.py 類物件整合子scrapy.Spider

5、修改settings.py配置檔案 ITEM_PIPELINES = {'BOSS.pipelines.WwwZhipinComPipeline':100}

6、編寫資料處理指令碼進行資料儲存,pipelines.py 類物件繼承自object

1
def process_item(self, item, spider): 2 with open("my_boss.txt", 'a') as fp: 3 fp.write(item['name'] + '\n')

7、執行爬蟲 cd BOSS 回車 scrapy crawl zhipin --nolog

注意:如果匯出的中文資訊亂碼則需要在settings.py檔案中配置編碼:FEED_EXPORT_ENCODING = 'utf-8'

三、環境安裝

    爬蟲框架我們使用Scrapy,爬取到的資料我們使用mongodb來儲存

1、安裝Scrapy

1 pip install Scrapy

2、安裝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使用

    上一小節我們已經安裝了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、輸入如下命令,建立zhipin爬蟲

1 scrapy startproject www_zhipin_com
2 cd www_zhipin_com 回車 scrapy gensipder zhipin www.zhipin.com

2、修改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.1、這裡有一個小技巧,我們重寫start_requests方法,讓他呼叫了我們自己寫的一個方法next_request,並設定了回撥函式為parse方法,當parse資料解析完畢後,又構造一個新的url在次呼叫next_request方法拉取資料,一直迴圈迭代,拉取資料、解析資料

2.2、boss直聘有一個限制,不管以什麼樣的方式搜尋資料,資料最多顯示10頁,這也就要求我們需要對爬蟲做一個處理,在合適的實際去終止拉取資料,否則爬蟲會一直執行下去,直到boss直聘返回異常(請求被限制)

2.3、經過對爬蟲資料的分析,我們發現當最後一次請求和上一次請求的資料完全一樣時,我們可能已經到達請求的最後一頁,那麼這個時候我們就可以去終止爬蟲了

2.4、為了快速的比對我麼爬取到的資料是否和上一次一樣,我們對爬取到的資料進行簡單的處理,每次去對比關鍵欄位即可

 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.5、一次請求的資料是一個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.6、parse解析資料時,對每一條資料會構造一個WwwZhipinComItem物件item,並通過yield item方式觸發

3、對於爬取的欄位定義需要我們修改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、最後一步寫入資料庫

4.1、第四節我們封裝了一個名字為my_connect的資料庫操作物件,在這裡我們就可以用上了。

4.2、首先構造一個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.3、指定要插入的集合,然後構造資料、插入資料

 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.4、資料爬取結束後,使用gui工具Navicat 12 for MongoDB可以檢視爬取到的資料,效果如下圖所示

六、原始碼下載

  需要全部程式碼的到csdn直接下載:python爬蟲Scrapy(一)-我爬了boss資料

 

轉載宣告:本站文章無特別說明,皆為原創,版權所有,轉載請註明:朝十晚八