Python爬蟲框架Scrapy實戰(zhàn)之批量抓取招聘信息
網絡爬蟲抓取特定網站網頁的html數(shù)據(jù),但是一個網站有上千上萬條數(shù)據(jù),我們不可能知道網站網頁的url地址,所以,要有個技巧去抓取網站的所有html頁面。Scrapy是純Python實現(xiàn)的爬蟲框架,用戶只需要定制開發(fā)幾個模塊就可以輕松的實現(xiàn)一個爬蟲,用來抓取網頁內容以及各種圖片,非常之方便~
Scrapy 使用wisted這個異步網絡庫來處理網絡通訊,架構清晰,并且包含了各種中間件接口,可以靈活的完成各種需求。整體架構如下圖所示:
綠線是數(shù)據(jù)流向,首先從初始URL 開始,Scheduler 會將其交給 Downloader 進行下載,下載之后會交給 Spider 進行分析,Spider分析出來的結果有兩種:一種是需要進一步抓取的鏈接,例如之前分析的“下一頁”的鏈接,這些東西會被傳回 Scheduler ;另一種是需要保存的數(shù)據(jù),它們則被送到Item Pipeline 那里,那是對數(shù)據(jù)進行后期處理(詳細分析、過濾、存儲等)的地方。另外,在數(shù)據(jù)流動的通道里還可以安裝各種中間件,進行必要的處理。
我假定你已經安裝了Scrapy。假如你沒有安裝,你可以參考這篇文章。
在本文中,我們將學會如何使用Scrapy建立一個爬蟲程序,并爬取指定網站上的內容
1. 創(chuàng)建一個新的Scrapy Project
2. 定義你需要從網頁中提取的元素Item
3.實現(xiàn)一個Spider類,通過接口完成爬取URL和提取Item的功能
4. 實現(xiàn)一個Item PipeLine類,完成Item的存儲功能
我將會用騰訊招聘官網作為例子。
Github源碼:https://github.com/maxliaops/scrapy-itzhaopin
目標:抓取騰訊招聘官網職位招聘信息并保存為JSON格式。
新建工程
首先,為我們的爬蟲新建一個工程,首先進入一個目錄(任意一個我們用來保存代碼的目錄),執(zhí)行:
scrapy startprojectitzhaopin
最后的itzhaopin就是項目名稱。這個命令會在當前目錄下創(chuàng)建一個新目錄itzhaopin,結構如下:
├── itzhaopin
│ ├── itzhaopin
│ │ ├── __init__.py
│ │ ├── items.py
│ │ ├── pipelines.py
│ │ ├── settings.py
│ │ └── spiders
│ │ └── __init__.py
│ └── scrapy.cfg
scrapy.cfg: 項目配置文件
items.py: 需要提取的數(shù)據(jù)結構定義文件
pipelines.py:管道定義,用來對items里面提取的數(shù)據(jù)做進一步處理,如保存等
settings.py: 爬蟲配置文件
spiders: 放置spider的目錄
定義Item
在items.py里面定義我們要抓取的數(shù)據(jù):
from scrapy.item import Item, Field class TencentItem(Item): name = Field() # 職位名稱 catalog = Field() # 職位類別 workLocation = Field() # 工作地點 recruitNumber = Field() # 招聘人數(shù) detailLink = Field() # 職位詳情頁鏈接 publishTime = Field() # 發(fā)布時間
實現(xiàn)Spider
Spider是一個繼承自scrapy.contrib.spiders.CrawlSpider的Python類,有三個必需的定義的成員
name: 名字,這個spider的標識
start_urls:一個url列表,spider從這些網頁開始抓取
parse():一個方法,當start_urls里面的網頁抓取下來之后需要調用這個方法解析網頁內容,同時需要返回下一個需要抓取的網頁,或者返回items列表
所以在spiders目錄下新建一個spider,tencent_spider.py:
import re import json from scrapy.selector import Selector try: from scrapy.spider import Spider except: from scrapy.spider import BaseSpider as Spider from scrapy.utils.response import get_base_url from scrapy.utils.url import urljoin_rfc from scrapy.contrib.spiders import CrawlSpider, Rule from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor as sle from itzhaopin.items import * from itzhaopin.misc.log import * class TencentSpider(CrawlSpider): name = "tencent" allowed_domains = ["tencent.com"] start_urls = [ "http://hr.tencent.com/position.php" ] rules = [ # 定義爬取URL的規(guī)則 Rule(sle(allow=("/position.php\?&start=\d{,4}#a")), follow=True, callback='parse_item') ] def parse_item(self, response): # 提取數(shù)據(jù)到Items里面,主要用到XPath和CSS選擇器提取網頁數(shù)據(jù) items = [] sel = Selector(response) base_url = get_base_url(response) sites_even = sel.css('table.tablelist tr.even') for site in sites_even: item = TencentItem() item['name'] = site.css('.l.square a').xpath('text()').extract() relative_url = site.css('.l.square a').xpath('@href').extract()[0] item['detailLink'] = urljoin_rfc(base_url, relative_url) item['catalog'] = site.css('tr > td:nth-child(2)::text').extract() item['workLocation'] = site.css('tr > td:nth-child(4)::text').extract() item['recruitNumber'] = site.css('tr > td:nth-child(3)::text').extract() item['publishTime'] = site.css('tr > td:nth-child(5)::text').extract() items.append(item) #print repr(item).decode("unicode-escape") + '\n' sites_odd = sel.css('table.tablelist tr.odd') for site in sites_odd: item = TencentItem() item['name'] = site.css('.l.square a').xpath('text()').extract() relative_url = site.css('.l.square a').xpath('@href').extract()[0] item['detailLink'] = urljoin_rfc(base_url, relative_url) item['catalog'] = site.css('tr > td:nth-child(2)::text').extract() item['workLocation'] = site.css('tr > td:nth-child(4)::text').extract() item['recruitNumber'] = site.css('tr > td:nth-child(3)::text').extract() item['publishTime'] = site.css('tr > td:nth-child(5)::text').extract() items.append(item) #print repr(item).decode("unicode-escape") + '\n' info('parsed ' + str(response)) return items def _process_request(self, request): info('process ' + str(request)) return request
實現(xiàn)PipeLine
PipeLine用來對Spider返回的Item列表進行保存操作,可以寫入到文件、或者數(shù)據(jù)庫等。
PipeLine只有一個需要實現(xiàn)的方法:process_item,例如我們將Item保存到JSON格式文件中:
pipelines.py
from scrapy import signals import json import codecs class JsonWithEncodingTencentPipeline(object): def __init__(self): self.file = codecs.open('tencent.json', 'w', encoding='utf-8') def process_item(self, item, spider): line = json.dumps(dict(item), ensure_ascii=False) + "\n" self.file.write(line) return item def spider_closed(self, spider): self.file.close( )
到現(xiàn)在,我們就完成了一個基本的爬蟲的實現(xiàn),可以輸入下面的命令來啟動這個Spider
scrapy crawl tencent
爬蟲運行結束后,在當前目錄下將會生成一個名為tencent.json的文件,其中以JSON格式保存了職位招聘信息。
部分內容如下:
{"recruitNumber": ["1"], "name": ["SD5-資深手游策劃(深圳)"], "detailLink": " ["2014-04-25"], "catalog": ["產品/項目類"], "workLocation": ["深圳"]}
{"recruitNumber": ["1"], "name": ["TEG13-后臺開發(fā)工程師(深圳)"], "detailLink": " "publishTime": ["2014-04-25"], "catalog": ["技術類"], "workLocation": ["深圳"]}
{"recruitNumber": ["2"], "name": ["TEG12-數(shù)據(jù)中心高級經理(深圳)"], "detailLink": " "publishTime": ["2014-04-25"], "catalog": ["技術類"], "workLocation": ["深圳"]}
{"recruitNumber": ["1"], "name": ["GY1-微信支付品牌策劃經理(深圳)"], "detailLink": " "publishTime": ["2014-04-25"], "catalog": ["市場類"], "workLocation": ["深圳"]}
{"recruitNumber": ["2"], "name": ["SNG06-后臺開發(fā)工程師(深圳)"], "detailLink": " "publishTime": ["2014-04-25"], "catalog": ["技術類"], "workLocation": ["深圳"]}
{"recruitNumber": ["2"], "name": ["OMG01-騰訊時尚視頻策劃編輯(北京)"], "detailLink": " "publishTime": ["2014-04-25"], "catalog": ["內容編輯類"], "workLocation": ["北京"]}
{"recruitNumber": ["1"], "name": ["HY08-QT客戶端Windows開發(fā)工程師(深圳)"], "detailLink": " "publishTime": ["2014-04-25"], "catalog": ["技術類"], "workLocation": ["深圳"]}
{"recruitNumber": ["5"], "name": ["HY1-移動游戲測試經理(上海)"], "detailLink": "
{"recruitNumber": ["1"], "name": ["HY6-網吧平臺高級產品經理(深圳)"], "detailLink": "
{"recruitNumber": ["4"], "name": ["TEG14-云存儲研發(fā)工程師(深圳)"], "detailLink": "
{"recruitNumber": ["1"], "name": ["CB-薪酬經理(深圳)"], "detailLink": "
以上全部內容就是通過Python爬蟲框架Scrapy實戰(zhàn)之批量抓取招聘信息的全部內容,希望對大家有所幫助,欲了解更多編程知識,請鎖定我們的網站,每天都有新的內容發(fā)布。
相關文章
Python深度學習實戰(zhàn)PyQt5菜單和工具欄功能作用
本文詳細解讀通過 QtDesigner 創(chuàng)建主窗口、菜單欄和工具欄,并以菜單項 “退出” 為例關聯(lián)系統(tǒng)定義的動作處理方法。有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10python web框架Flask實現(xiàn)圖形驗證碼及驗證碼的動態(tài)刷新實例
在本篇文章里小編給大家整理的是關于python web框架Flask實現(xiàn)圖形驗證碼的相關知識點,有需要的朋友們參考下。2019-10-10詳解python os.path.exists判斷文件或文件夾是否存在
這篇文章主要介紹了詳解python os.path.exists判斷文件或文件夾是否存在,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-11-11python實現(xiàn)讀取excel寫入mysql的小工具詳解
EXCEL 和 MySQL 大體上來說都可以算是"數(shù)據(jù)庫",MySQL貌似有EXCEL的接口,但是最近在自學Python,用Python實現(xiàn)了一下,下面這篇文章主要給大家介紹了關于利用python實現(xiàn)讀取excel寫入mysql的一個小工具,需要的朋友可以參考下。2017-11-11