Python scrapy增量爬取實(shí)例及實(shí)現(xiàn)過程解析
這篇文章主要介紹了Python scrapy增量爬取實(shí)例及實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
開始接觸爬蟲的時(shí)候還是初學(xué)Python的那會(huì),用的還是request、bs4、pandas,再后面接觸scrapy做個(gè)一兩個(gè)爬蟲,覺得還是框架好,可惜都沒有記錄都忘記了,現(xiàn)在做推薦系統(tǒng)需要爬取一定的文章,所以又把scrapy撿起來。趁著這次機(jī)會(huì)做一個(gè)記錄。
目錄如下:
- 環(huán)境
- 本地窗口調(diào)試命令
- 工程目錄
- xpath選擇器
- 一個(gè)簡單的增量爬蟲示例
- 配置介紹
環(huán)境
自己的環(huán)境下安裝scrapy肯定用anaconda(再次強(qiáng)調(diào)anaconda的優(yōu)越性
本地窗口調(diào)試與運(yùn)行
開發(fā)的時(shí)候可以利用scrapy自帶的調(diào)試功能進(jìn)行模擬請(qǐng)求,這樣request、response都會(huì)與后面代碼保持一樣。
# 測試請(qǐng)求某網(wǎng)站 scrapy shell URL # 設(shè)置請(qǐng)求頭 scrapy shell -s USER_AGENT="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" URL # 指定爬蟲內(nèi)容輸出文件格式(json、csv等 scrapy crawl SPIDER_NAME -o FILE_NAME.csv # 創(chuàng)建爬蟲工程 scrapy startproject articles # 在當(dāng)前目錄創(chuàng)建一個(gè)scrapy工程
新工程結(jié)構(gòu)介紹
# spiders文件下存放所有爬蟲,item.py格式化數(shù)據(jù)輸出 # middlewares.py 設(shè)置請(qǐng)求細(xì)節(jié)(請(qǐng)求頭之類的),pipelines.py為數(shù)據(jù)輸出的管道,每一個(gè)封裝好的item都會(huì)經(jīng)過這里 # settings.py 對(duì)工程進(jìn)行全局設(shè)置(存放配置 ├── articles │ ├── articles │ │ ├── __init__.py │ │ ├── items.py │ │ ├── middlewares.py │ │ ├── pipelines.py │ │ ├── settings.py │ │ └── spiders │ │ ├── healthy_living.py │ │ ├── __init__.py │ │ └── people_health.py │ └── scrapy.cfg ├── README.en.md └── README.md
頁面解析神器——Xpath選擇器
scrapy自帶xpath選擇器,很方便,簡單介紹一些常用的
# 全站爬取神器--LinkExtractor,可以自動(dòng)獲取該標(biāo)簽下的所有url跟text(因?yàn)榫W(wǎng)站結(jié)構(gòu)大都一個(gè)套路
from scrapy.linkextractors import LinkExtractor
le = LinkExtractor(restrict_xpaths="http://ul[@class='nav2_UL_1 clearFix']")# 返回一個(gè)迭代器,通過循環(huán)(for i in le),可獲取url(i.url) (i.text)
# 獲取屬性class為所有aa的div標(biāo)簽內(nèi)容中的內(nèi)容
response.xpath("http://div[@class='aa']/text()").extract() # '//'代表獲取所有,'/'代表獲取第一個(gè),類似的可以找屬性為ul的其它標(biāo)簽
# 獲取內(nèi)容包含“下一頁”的所有a標(biāo)簽中包含的鏈接(提取下一頁鏈接神器
response.xpath("http://a[contains(text(),'下一頁')]/@href").extract()
一個(gè)簡單的增量爬取示例
這里增量爬取的思想很簡單:目標(biāo)網(wǎng)站的數(shù)據(jù)都是按照時(shí)間排列的,所以在對(duì)某個(gè)連接進(jìn)行request之前,先查詢數(shù)據(jù)庫中有沒有這條數(shù)據(jù),如果有,就停止爬蟲,如果沒有發(fā)起請(qǐng)求
class HealthyLiving(scrapy.Spider):
# 一定要一個(gè)全局唯一的爬蟲名稱,命令行啟動(dòng)的時(shí)候需要指定該名稱
name = "healthy_living"
# 指定爬蟲入口,scrapy支持多入口,所以一定是lis形式
start_urls = ['http://www.jkb.com.cn/healthyLiving/']
'''
抓取大類標(biāo)簽入口
'''
def parse(self, response):
le = LinkExtractor(restrict_xpaths="http://ul[@class='nav2_UL_1 clearFix']")
for link in le.extract_links(response)[1:-1]:
tag = link.text
# 將這一級(jí)提取到的信息,通過請(qǐng)求頭傳遞給下一級(jí)(這里是為了給數(shù)據(jù)打標(biāo)簽
meta = {"tag": tag}
# 依次解析每一個(gè)鏈接,并傳遞到下一級(jí)進(jìn)行繼續(xù)爬取
yield scrapy.Request(link.url, callback=self.parse_articles, meta=meta)
'''
抓取頁面內(nèi)的文章鏈接及下一頁鏈接
'''
def parse_articles(self, response):
# 接收上一級(jí)傳遞的信息
meta = response.meta
article_links = response.xpath("http://div[@class='txt']/h4/a/@href").extract()
for link in article_links:
res = self.collection.find_one({"article_url": link}, {"article_url": 1})
full_meta = dict(meta)
# 將文章鏈接傳入下一級(jí)
full_meta.update({"article_url": link})
if res is None:
yield scrapy.Request(link, callback=self.parse_article, meta=full_meta)
else:
return
next_page = response.xpath("http://div[@class='page']//a[contains(text(),'»')]/@href").extract()[0]
if next_page:
yield scrapy.Request(next_page, callback=self.parse_articles, meta=meta)
# 最后解析頁面,并輸出
def parse_article(self, response):
# 從item.py中導(dǎo)入數(shù)據(jù)封裝格式
article_item = ArticlesItem()
meta = response.meta
# 利用xpath提取頁面信息并封裝成item
try:
article_item["tag"] = ""
# ... 省略
finally:
yield article_item
工程配置介紹
設(shè)置請(qǐng)求頭、配置數(shù)據(jù)庫
# 設(shè)置請(qǐng)求頭,在middlewares.py中設(shè)定,在settings.py中啟用
class RandomUA(object):
user_agents = [
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit"
"/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11",
"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit"
"/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16"
]
def process_request(self, request, spider):
request.headers["User-Agent"] = random.choice(self.user_agents)
# 設(shè)置數(shù)據(jù)入庫處理,在pipeline.py進(jìn)行配置,在settings.py進(jìn)行啟用
class MongoPipeline(object):
def __init__(self, mongo_uri, mongo_db):
self.mongo_uri = mongo_uri
self.mongo_db = mongo_db
@classmethod
def from_crawler(cls, crawler):
return cls(
mongo_uri=crawler.settings.get('MONGO_URI'),
mongo_db=crawler.settings.get('MONGO_DB')
)
def open_spider(self, spider):
print("開始爬取", datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
self.client = pymongo.MongoClient(self.mongo_uri)
self.db = self.client[self.mongo_db]
def process_item(self, item, spider):
data = self.db[item.collection].find_one({"title": item["title"], "date": item["date"]})
if data is None:
self.db[item.collection].insert(dict(item))
# else:
# self.close_spider(self, spider)
return item
def close_spider(self, spider):
print("爬取結(jié)束", datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
self.client.close()
# 在settings.py啟動(dòng):請(qǐng)求頭的修改,數(shù)據(jù)庫的配置
DOWNLOADER_MIDDLEWARES = {
# 'articles.middlewares.ArticlesDownloaderMiddleware': 543,
'articles.middlewares.RandomUA': 543,# 543代表優(yōu)先級(jí),數(shù)字越低優(yōu)先級(jí)越高
}
ITEM_PIPELINES = {
'articles.pipelines.MongoPipeline': 300,
}
# 一些其它配置
ROBOTSTXT_OBEY = True # 是否遵守網(wǎng)站的robot協(xié)議
FEED_EXPORT_ENCODING = 'utf-8' # 指定數(shù)據(jù)輸出的編碼格式
## 數(shù)據(jù)庫配置
MONGO_URI = ''
MONGO_DB = ''
MONGO_PORT = 27017
MONGO_COLLECTION = ''
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Python爬蟲之教你利用Scrapy爬取圖片
- python基于scrapy爬取京東筆記本電腦數(shù)據(jù)并進(jìn)行簡單處理和分析
- python實(shí)現(xiàn)Scrapy爬取網(wǎng)易新聞
- Android開發(fā)Activity管理工具類的操作方法
- 如何在scrapy中集成selenium爬取網(wǎng)頁的方法
- 使用scrapy ImagesPipeline爬取圖片資源的示例代碼
- scrapy與selenium結(jié)合爬取數(shù)據(jù)(爬取動(dòng)態(tài)網(wǎng)站)的示例代碼
- Python利用Scrapy框架爬取豆瓣電影示例
- Python爬蟲實(shí)戰(zhàn)之使用Scrapy爬取豆瓣圖片
相關(guān)文章
Python連接達(dá)夢(mèng)數(shù)據(jù)庫的實(shí)現(xiàn)示例
本文主要介紹了Python連接達(dá)夢(mèng)數(shù)據(jù)庫的實(shí)現(xiàn)示例,dmPython是DM提供的依據(jù)Python DB API version 2.0中API使用規(guī)定而開發(fā)的數(shù)據(jù)庫訪問接口,使Python應(yīng)用程序能夠?qū)M數(shù)據(jù)庫進(jìn)行訪問2023-12-12
Python獲取android設(shè)備cpu和內(nèi)存占用情況
這篇文章主要介紹了Python獲取android設(shè)備cpu和內(nèi)存占用情況,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
Python Django 頁面上展示固定的頁碼數(shù)實(shí)現(xiàn)代碼
這篇文章主要介紹了Python Django 頁面上展示固定的頁碼數(shù)實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08
python判斷字符串以什么結(jié)尾的實(shí)例方法
在本篇文章里小編給大家整理了關(guān)于python判斷字符串以什么結(jié)尾的實(shí)例方法 ,需要的朋友們可以學(xué)習(xí)參考下。2020-09-09
Python OpenCV Hough直線檢測算法的原理實(shí)現(xiàn)
這篇文章主要介紹了Python OpenCV Hough直線檢測算法的原理實(shí)現(xiàn),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-07-07
Python使用mmap實(shí)現(xiàn)內(nèi)存映射文件操作
內(nèi)存映射通??梢蕴岣逫/O的性能,本文主要介紹了Python使用mmap實(shí)現(xiàn)內(nèi)存映射文件操作,分享給大家,感興趣的可以了解一下2021-06-06
Python使用pypinyin實(shí)現(xiàn)中文拼音轉(zhuǎn)換
pypinyin是一個(gè)Python庫,用于將中文漢字轉(zhuǎn)換為拼音,這篇文章主要為大家詳細(xì)介紹了pypinyin的基本用法并探討其應(yīng)用場景,需要的可以參考下2024-02-02
Python實(shí)戰(zhàn)練習(xí)之終于對(duì)肯德基下手
讀萬卷書不如行萬里路,學(xué)的扎不扎實(shí)要通過實(shí)戰(zhàn)才能看出來,本篇文章手把手帶你爬下肯德基的官網(wǎng),大家可以在過程中查缺補(bǔ)漏,看看自己掌握程度怎么樣2021-10-10

