您好,登錄后才能下訂單哦!
這篇文章主要介紹了Python scrapy增量爬取實例及實現過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
開始接觸爬蟲的時候還是初學Python的那會,用的還是request、bs4、pandas,再后面接觸scrapy做個一兩個爬蟲,覺得還是框架好,可惜都沒有記錄都忘記了,現在做推薦系統需要爬取一定的文章,所以又把scrapy撿起來。趁著這次機會做一個記錄。
目錄如下:
環境
自己的環境下安裝scrapy肯定用anaconda(再次強調anaconda的優越性
本地窗口調試與運行
開發的時候可以利用scrapy自帶的調試功能進行模擬請求,這樣request、response都會與后面代碼保持一樣。
# 測試請求某網站 scrapy shell URL # 設置請求頭 scrapy shell -s USER_AGENT="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" URL # 指定爬蟲內容輸出文件格式(json、csv等 scrapy crawl SPIDER_NAME -o FILE_NAME.csv # 創建爬蟲工程 scrapy startproject articles # 在當前目錄創建一個scrapy工程
新工程結構介紹
# spiders文件下存放所有爬蟲,item.py格式化數據輸出 # middlewares.py 設置請求細節(請求頭之類的),pipelines.py為數據輸出的管道,每一個封裝好的item都會經過這里 # settings.py 對工程進行全局設置(存放配置 ├── 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,可以自動獲取該標簽下的所有url跟text(因為網站結構大都一個套路 from scrapy.linkextractors import LinkExtractor le = LinkExtractor(restrict_xpaths="http://ul[@class='nav2_UL_1 clearFix']")# 返回一個迭代器,通過循環(for i in le),可獲取url(i.url) (i.text) # 獲取屬性class為所有aa的div標簽內容中的內容 response.xpath("http://div[@class='aa']/text()").extract() # '//'代表獲取所有,'/'代表獲取第一個,類似的可以找屬性為ul的其它標簽 # 獲取內容包含“下一頁”的所有a標簽中包含的鏈接(提取下一頁鏈接神器 response.xpath("http://a[contains(text(),'下一頁')]/@href").extract()
一個簡單的增量爬取示例
這里增量爬取的思想很簡單:目標網站的數據都是按照時間排列的,所以在對某個連接進行request之前,先查詢數據庫中有沒有這條數據,如果有,就停止爬蟲,如果沒有發起請求
class HealthyLiving(scrapy.Spider): # 一定要一個全局唯一的爬蟲名稱,命令行啟動的時候需要指定該名稱 name = "healthy_living" # 指定爬蟲入口,scrapy支持多入口,所以一定是lis形式 start_urls = ['http://www.jkb.com.cn/healthyLiving/'] ''' 抓取大類標簽入口 ''' 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 # 將這一級提取到的信息,通過請求頭傳遞給下一級(這里是為了給數據打標簽 meta = {"tag": tag} # 依次解析每一個鏈接,并傳遞到下一級進行繼續爬取 yield scrapy.Request(link.url, callback=self.parse_articles, meta=meta) ''' 抓取頁面內的文章鏈接及下一頁鏈接 ''' def parse_articles(self, response): # 接收上一級傳遞的信息 meta = response.meta article_links = response.xpath("http://div[@class='txt']/h5/a/@href").extract() for link in article_links: res = self.collection.find_one({"article_url": link}, {"article_url": 1}) full_meta = dict(meta) # 將文章鏈接傳入下一級 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中導入數據封裝格式 article_item = ArticlesItem() meta = response.meta # 利用xpath提取頁面信息并封裝成item try: article_item["tag"] = "" # ... 省略 finally: yield article_item
工程配置介紹
設置請求頭、配置數據庫
# 設置請求頭,在middlewares.py中設定,在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) # 設置數據入庫處理,在pipeline.py進行配置,在settings.py進行啟用 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("爬取結束", datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')) self.client.close() # 在settings.py啟動:請求頭的修改,數據庫的配置 DOWNLOADER_MIDDLEWARES = { # 'articles.middlewares.ArticlesDownloaderMiddleware': 543, 'articles.middlewares.RandomUA': 543,# 543代表優先級,數字越低優先級越高 } ITEM_PIPELINES = { 'articles.pipelines.MongoPipeline': 300, } # 一些其它配置 ROBOTSTXT_OBEY = True # 是否遵守網站的robot協議 FEED_EXPORT_ENCODING = 'utf-8' # 指定數據輸出的編碼格式 ## 數據庫配置 MONGO_URI = '' MONGO_DB = '' MONGO_PORT = 27017 MONGO_COLLECTION = ''
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。