Scrapy
步驟:
新建項(xiàng)目 (Project):新建一個(gè)新的爬蟲項(xiàng)目
明確目標(biāo)(Items):明確你想要抓取的目標(biāo)
制作爬蟲(Spider):制作爬蟲開始爬取網(wǎng)頁
存儲(chǔ)內(nèi)容(Pipeline):設(shè)計(jì)管道存儲(chǔ)爬取內(nèi)容
Python開發(fā)的一個(gè)快速,高層次的屏幕抓取和web抓取框架偿曙,用于抓取web站點(diǎn)并從頁面中提取結(jié)構(gòu)化的數(shù)據(jù)。Scrapy用途廣泛糖耸,可以用于數(shù)據(jù)挖掘、監(jiān)測(cè)和自動(dòng)化測(cè)試桶现。
Scratch超棺,是抓取的意思,這個(gè)Python的爬蟲框架叫Scrapy
Scrapy 使用了 Twisted異步網(wǎng)絡(luò)庫來處理網(wǎng)絡(luò)通訊 結(jié)構(gòu)圖
Scrapy主要包括了以下組件:
1).引擎(Scrapy)
用來處理整個(gè)系統(tǒng)的數(shù)據(jù)流處理, 觸發(fā)事務(wù)(框架核心)
2).調(diào)度器(Scheduler)
用來接受引擎發(fā)過來的請(qǐng)求, 壓入隊(duì)列中, 并在引擎再次請(qǐng)求的時(shí)候返回. 可以想像成一個(gè)URL(抓取網(wǎng)頁的網(wǎng)址或者說是鏈接)的優(yōu)先隊(duì)列, 由它來決定下一個(gè)要抓取的網(wǎng)址是什么, 同時(shí)去除重復(fù)的網(wǎng)址
3).下載器(Downloader)
用于下載網(wǎng)頁內(nèi)容, 并將網(wǎng)頁內(nèi)容返回給蜘蛛(Scrapy下載器是建立在twisted這個(gè)高效的異步模型上的)
4).爬蟲(Spiders)
爬蟲是主要干活的, 用于從特定的網(wǎng)頁中提取自己需要的信息, 即所謂的實(shí)體(Item)差油。用戶也可以從中提取出鏈接,讓Scrapy繼續(xù)抓取下一個(gè)頁面
5).項(xiàng)目管道(Pipeline)
負(fù)責(zé)處理爬蟲從網(wǎng)頁中抽取的實(shí)體泳炉,主要的功能是持久化實(shí)體憾筏、驗(yàn)證實(shí)體的有效性、清除不需要的信息花鹅。當(dāng)頁面被爬蟲解析后氧腰,將被發(fā)送到項(xiàng)目管道,并經(jīng)過幾個(gè)特定的次序處理數(shù)據(jù)。
6).下載器中間件(Downloader Middlewares)
位于Scrapy引擎和下載器之間的框架古拴,主要是處理Scrapy引擎與下載器之間的請(qǐng)求及響應(yīng)箩帚。
7).爬蟲中間件(Spider Middlewares)
介于Scrapy引擎和爬蟲之間的框架,主要工作是處理蜘蛛的響應(yīng)輸入和請(qǐng)求輸出斤富。
8).調(diào)度中間件(Scheduler Middewares)
介于Scrapy引擎和調(diào)度之間的中間件膏潮,從Scrapy引擎發(fā)送到調(diào)度的請(qǐng)求和響應(yīng)锻狗。
安裝方式
Ubuntu 安裝方式
通過pip3 安裝 Scrapy 框架
sudo pip3 install scrapy
如果安裝不成功再試著添加這些依賴庫:
安裝非Python的依賴
sudo apt-get install python3-dev python-pip libxml2-dev libxslt1-dev zlib1g-dev libffi-dev libssl-dev
創(chuàng)建項(xiàng)目
終端打開
scrapy startproject + 項(xiàng)目名稱
cd + 項(xiàng)目名稱
cd +項(xiàng)目名稱
cd spider
scrapy genspider + 項(xiàng)目名稱 + 域(如:baidu.com)
如果有虛擬環(huán)境 進(jìn)入虛擬環(huán)境后再操作
項(xiàng)目創(chuàng)建完畢后满力,關(guān)閉終端
使用編輯器打開項(xiàng)目
項(xiàng)目?jī)?nèi)各文件作用
spiders 爬蟲目錄,如:創(chuàng)建文件轻纪,編寫爬蟲規(guī)則 存儲(chǔ)爬蟲的目錄
spider文件下
項(xiàng)目.py
# -*- coding: utf-8 -*-
import scrapy
from tencent.items import TencentItem
class TencentpositionSpider(scrapy.Spider):
"""
功能:爬取騰訊社招信息
"""
# 爬蟲名
name = "tencentPosition"
# 爬蟲作用范圍
allowed_domains = ["tencent.com"]
url = "http://hr.tencent.com/position.php?&start="
offset = 0
# 起始url
start_urls = [url + str(offset)]
def parse(self, response):
for each in response.xpath("http://tr[@class='even'] | //tr[@class='odd']"):
# 初始化模型對(duì)象
item = TencentItem()
# 職位名稱
item['positionname'] = each.xpath("./td[1]/a/text()").extract()[0]
# 詳情連接
item['positionlink'] = each.xpath("./td[1]/a/@href").extract()[0]
# 職位類別
item['positionType'] = each.xpath("./td[2]/text()").extract()[0]
# 招聘人數(shù)
item['peopleNum'] = each.xpath("./td[3]/text()").extract()[0]
# 工作地點(diǎn)
item['workLocation'] = each.xpath("./td[4]/text()").extract()[0]
# 發(fā)布時(shí)間
item['publishTime'] = each.xpath("./td[5]/text()").extract()[0]
yield item
if self.offset < 1680:
self.offset += 10
# 每次處理完一頁的數(shù)據(jù)之后油额,重新發(fā)送下一頁頁面請(qǐng)求
# self.offset自增10,同時(shí)拼接為新的url刻帚,并調(diào)用回調(diào)函數(shù)self.parse處理Response
yield scrapy.Request(self.url + str(self.offset), callback = self.parse)
scrapy.cfg 項(xiàng)目的配置信息潦嘶,主要為Scrapy命令行工具提供一個(gè)基礎(chǔ)的配置信息。(真正爬蟲相關(guān)的配置信息在settings.py文件中)
items.py 設(shè)置數(shù)據(jù)存儲(chǔ)模板崇众,用于結(jié)構(gòu)化數(shù)據(jù)掂僵,如:Django的Model
在Scrapy中,items是用來加載抓取內(nèi)容的容器顷歌,有點(diǎn)像Python中的Dic锰蓬,也就是字典,但是提供了一些額外的保護(hù)減少錯(cuò)誤眯漩。
一般來說芹扭,item可以用scrapy.item.Item類來創(chuàng)建,并且用scrapy.item.Field對(duì)象來定義屬性(可以理解成類似于ORM的映射關(guān)系)赦抖。
接下來舱卡,開始來構(gòu)建item模型(model)。
首先队萤,想要的內(nèi)容有:
- 名稱(name)
- 鏈接(url)
- 描述(description)
可以把Item簡(jiǎn)單的理解成封裝好的類對(duì)象轮锥。
# -*- coding:utf-8 -*-
import scrapy
# 導(dǎo)入CrawlSpider類和Rule
from scrapy.spiders import CrawlSpider, Rule
# 導(dǎo)入鏈接規(guī)則匹配類,用來提取符合規(guī)則的連接
from scrapy.linkextractors import LinkExtractor
from TencentSpider.items import TencentItem
class TencentSpider(CrawlSpider):
name = "tencent"
allow_domains = ["hr.tencent.com"]
start_urls = ["http://hr.tencent.com/position.php?&start=0#a"]
# Response里鏈接的提取規(guī)則要尔,返回的符合匹配規(guī)則的鏈接匹配對(duì)象的列表
pagelink = LinkExtractor(allow=("start=\d+"))
rules = [
# 獲取這個(gè)列表里的鏈接舍杜,依次發(fā)送請(qǐng)求,并且繼續(xù)跟進(jìn)盈电,調(diào)用指定回調(diào)函數(shù)處理
Rule(pagelink, callback = "parseTencent", follow = True)
]
# 指定的回調(diào)函數(shù)
def parseTencent(self, response):
for each in response.xpath("http://tr[@class='even'] | //tr[@class='odd']"):
item = TencentItem()
# 職位名稱
item['positionname'] = each.xpath("./td[1]/a/text()").extract()[0]
# 詳情連接
item['positionlink'] = each.xpath("./td[1]/a/@href").extract()[0]
# 職位類別
item['positionType'] = each.xpath("./td[2]/text()").extract()[0]
# 招聘人數(shù)
item['peopleNum'] = each.xpath("./td[3]/text()").extract()[0]
# 工作地點(diǎn)
item['workLocation'] = each.xpath("./td[4]/text()").extract()[0]
# 發(fā)布時(shí)間
item['publishTime'] = each.xpath("./td[5]/text()").extract()[0]
yield item
pipelines 存儲(chǔ)內(nèi)容
保存信息的最簡(jiǎn)單的方法是通過Feed exports蝴簇,主要有四種:JSON,JSON lines匆帚,CSV熬词,XML。我們將結(jié)果用最常用的JSON導(dǎo)出
數(shù)據(jù)處理行為,如:一般結(jié)構(gòu)化的數(shù)據(jù)持久化
# -*- coding: utf-8 -*-
import json
class TencentPipeline(object):
"""
功能:保存item數(shù)據(jù)
"""
def __init__(self):
self.filename = open("tencent.json", "w")
def process_item(self, item, spider):
text = json.dumps(dict(item), ensure_ascii = False) + ",\n"
self.filename.write(text.encode("utf-8"))
return item
def close_spider(self, spider):
self.filename.close()
settings.py 配置文件互拾,如:遞歸的層數(shù)歪今、并發(fā)數(shù),延遲下載等
True 改成 Flase
添加 UA
# 設(shè)置請(qǐng)求頭部颜矿,添加url
DEFAULT_REQUEST_HEADERS = {
"User-Agent" : "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;",
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
}
# 設(shè)置item——pipelines
ITEM_PIPELINES = {
'tencent.pipelines.TencentPipeline': 300,
}
運(yùn)行命令
scrapy crawl + 項(xiàng)目
parse():解析的方法寄猩,調(diào)用的時(shí)候傳入從每一個(gè)URL傳回的Response對(duì)象作為唯一參數(shù),負(fù)責(zé)解析并匹配抓取的數(shù)據(jù)(解析為item)骑疆,跟蹤更多的URL