python爬蟲Scrapy(一)-我爬了boss數據

1、概述

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

2、Scrapy框架使用步驟

    下面咱們作一個簡單示例,建立一個名字爲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'

3、環境安裝

    爬蟲框架咱們使用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

4、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'})

5、建立爬蟲zhipin

一、輸入以下命令,建立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能夠查看爬取到的數據,效果以下圖所示

6、源碼下載

  須要所有代碼的到csdn直接下載:python爬蟲Scrapy(一)-我爬了boss數據

 

若是您以爲文章不錯,不妨給個打賞,寫做不易,感謝各位的支持。您的支持是我最大的動力,謝謝!!! 

 

  


很重要--轉載聲明

  1. 本站文章無特別說明,皆爲原創,版權全部,轉載時請用連接的方式,給出原文出處。同時寫上原做者:朝十晚八 or Twowords
  2. 如要轉載,請原文轉載,如在轉載時修改本文,請事先告知,謝絕在轉載時經過修改本文達到有利於轉載者的目的。 

相關文章
相關標籤/搜索