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


一、概述

    學習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數據

 

如果您覺得文章不錯,不妨給個打賞,寫作不易,感謝各位的支持。您的支持是我最大的動力,謝謝!!! 

 

  


很重要--轉載聲明

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM