偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

人人都會(huì)數(shù)據(jù)采集- Scrapy 爬蟲框架入門

安全 應(yīng)用安全
在這個(gè)言必稱“大數(shù)據(jù)”“人工智能”的時(shí)代,數(shù)據(jù)分析與挖掘逐漸成為互聯(lián)網(wǎng)從業(yè)者必備的技能。本文介紹了利用輕量級(jí)爬蟲框架 scrapy 來進(jìn)行數(shù)據(jù)采集的基本方法。

在這個(gè)言必稱“大數(shù)據(jù)”“人工智能”的時(shí)代,數(shù)據(jù)分析與挖掘逐漸成為互聯(lián)網(wǎng)從業(yè)者必備的技能。本文介紹了利用輕量級(jí)爬蟲框架 scrapy 來進(jìn)行數(shù)據(jù)采集的基本方法。

一、scrapy簡(jiǎn)介

scrapy 是一套用 Python 編寫的異步爬蟲框架,基于 Twisted 實(shí)現(xiàn),運(yùn)行于 Linux/Windows/MacOS 等多種環(huán)境,具有速度快、擴(kuò)展性強(qiáng)、使用簡(jiǎn)便等特點(diǎn)。即便是新手也能迅速掌握并編寫出所需要的爬蟲程序。scrapy 可以在本地運(yùn)行,也能部署到云端(scrapyd)實(shí)現(xiàn)真正的生產(chǎn)級(jí)數(shù)據(jù)采集系統(tǒng)。

我們通過一個(gè)實(shí)例來學(xué)習(xí)如何利用 scrapy 從網(wǎng)絡(luò)上采集數(shù)據(jù)。“博客園”是一個(gè)技術(shù)類的綜合資訊網(wǎng)站,本次我們的任務(wù)是采集該網(wǎng)站 MySQL 類別

https://www.cnblogs.com/cate/mysql/ 下所有文章的標(biāo)題、摘要、發(fā)布日期、閱讀數(shù)量,共4個(gè)字段。最終的成果是一個(gè)包含了所有4個(gè)字段的文本文件。如圖所示:

scrapy 從網(wǎng)絡(luò)上采集數(shù)據(jù)

最終拿到的數(shù)據(jù)如下所示,每條記錄有四行,分別是標(biāo)題、閱讀數(shù)量、發(fā)布時(shí)間、文章摘要:

scrapy 從網(wǎng)絡(luò)上采集數(shù)據(jù)

二、安裝scrapy

下面來看看怎么安裝 scrapy。首先你的系統(tǒng)里必須得有 Python 和 pip,本文以最常見的 Python2.7.5 版本為例。pip 是 Python 的包管理工具,一般來說 Linux 系統(tǒng)中都會(huì)默認(rèn)安裝。在命令行下輸入如下命令并執(zhí)行:

  1. sudo pip install scrapy -i http://pypi.douban.com/simple –trusted-host=pypi.douban.com 

pip 會(huì)從豆瓣網(wǎng)的軟件源下載并安裝 scrapy,所有依賴的包都會(huì)被自動(dòng)下載安裝。”sudo”的意思是以超級(jí)用戶的權(quán)限執(zhí)行這條命令。所有的進(jìn)度條都走完之后,如果提示類似”Successfully installed Twisted, scrapy … “,則說明安裝成功。

三、scrapy交互環(huán)境

scrapy 同時(shí)也提供了一個(gè)可交互運(yùn)行的 Shell,能夠供我們方便地測(cè)試解析規(guī)則。scrapy 安裝成功之后,在命令行輸入 scrapy shell 即可啟動(dòng) scrapy 的交互環(huán)境。scrapy shell 的提示符是三個(gè)大于號(hào)>>>,表示可以接收命令了。我們先用 fetch() 方法來獲取首頁(yè)內(nèi)容:

  1. >>> fetch( “https://www.cnblogs.com/cate/mysql/” ) 

如果屏幕上有如下輸出,則說明網(wǎng)頁(yè)內(nèi)容已經(jīng)獲取到了。

  1. 2017-09-04 07:46:55 [scrapy.core.engine] INFO: Spider opened 
  2. 2017-09-04 07:46:55 [scrapy.core.engine] DEBUG: Crawled (200)  
  3. <GET https://www.cnblogs.com/cate/mysql/> (referer: None) 

獲取到的響應(yīng)會(huì)保存在 response 對(duì)象中。該對(duì)象的 status 屬性表示 HTTP 響應(yīng)狀態(tài),正常情況為 200。

  1. >>> print response.status 
  2. 200 

text 屬性表示返回的內(nèi)容數(shù)據(jù),從這些數(shù)據(jù)中可以解析出需要的內(nèi)容。

  1. >>> print response.text 
  2.  
  3. u'<!DOCTYPE html>\r\n<html lang=”zh-cn”>\r\n<head>\r\n     
  4. <meta charset=”utf-8″ />\r\n     
  5. <meta name=”viewport” content=”width=device-width, initial-scale=1″ />\r\n     
  6. <meta name=”referrer” content=”always” />\r\n     
  7. <title>MySQL – \u7f51\u7ad9\u5206\u7c7b – \u535a\u5ba2\u56ed</title>\r\n         
  8. <link rel=”shortcut icon” href=”//common.cnblogs.com/favicon.ico” type=”image/x-icon” />’ 

可以看到是一堆很亂的 HTML 代碼,沒法直觀地找到我們需要的數(shù)據(jù)。這個(gè)時(shí)候我們可以通過瀏覽器的“開發(fā)者工具”來獲取指定數(shù)據(jù)的 DOM 路徑。用瀏覽器打開網(wǎng)頁(yè) https://www.cnblogs.com/cate/mysql/ 之后,按下 F12 鍵即可啟動(dòng)開發(fā)者工具,并迅速定位指定的內(nèi)容。

可以看到我們需要的4個(gè)字段都在 / body / div(id=”wrapper”) / div(id=”main”) / div(id=”post_list”) / div(class=”post_item”) / div(class=”post_item_body”) / 下,每一個(gè)”post_item_body”都包含一篇文章的標(biāo)題、摘要、發(fā)布日期、閱讀數(shù)量。我們先獲取所有的”post_item_body”,然后再?gòu)睦锩娣謩e解析出每篇文章的4個(gè)字段。

  1. >>> post_item_body = response.xpath( “//div[@id=’wrapper’]/div[@id=’main’]/div[@id=’post_list’]/div[@class=’post_item’]/div[@class=’post_item_body’]” ) 
  2. >>> len( post_item_body ) 
  3. 20 

response 的 xpath 方法能夠利用 xpath 解析器獲取 DOM 數(shù)據(jù),xpath 的語法請(qǐng)參考官網(wǎng)文檔。可以看到我們拿到了首頁(yè)所有 20 篇文章的 post_item_body。那么如何將每篇文章的這4個(gè)字段提取出來呢?

我們以***篇文章為例。先取***個(gè) post_item_body:

  1. >>> first_article = post_item_body[ 0 ] 

標(biāo)題在 post_item_body 節(jié)點(diǎn)下的 h3 / a 中,xpath 方法中text()的作用是取當(dāng)前節(jié)點(diǎn)的文字,extract_first() 和 strip() 則是將 xpath 表達(dá)式中的節(jié)點(diǎn)提取出來并過濾掉前后的空格和回車符:

  1. >>> article_title = first_article.xpath( “h3/a/text()” ).extract_first().strip() 
  2. >>> print article_title 
  3. Mysql之表的操作與索引操作 

然后用類似的方式提取出文章摘要:

  1. >>> article_summary = first_article.xpath( “p[@class=’post_item_summary’]/text()” ).extract_first().strip() 
  2. >>> print article_summary 
  3. 表的操作: 1.表的創(chuàng)建: create table if not exists table_name(字段定義); 例子: create table if not exists user(id int auto_increment, uname varchar(20), address varch … 

在提取 post_item_foot 的時(shí)候,發(fā)現(xiàn)提取出了兩組內(nèi)容,***組是空內(nèi)容,第二組才是“發(fā)布于 XXX”的文字。我們將第二組內(nèi)容提取出來,并過濾掉“發(fā)布于”三個(gè)字:

  1. >>> post_date = first_article.xpath( “div[@class=’post_item_foot’]/text()” ).extract()[ 1 ].split( “發(fā)布于” )[ 1 ].strip() 
  2. >>> print post_date 
  3. 2017-09-03 18:13 

***將閱讀數(shù)量提取出來:

  1. >>> article_view = first_article.xpath( “div[@class=’post_item_foot’]/span[@class=’article_view’]/a/text()” ).extract_first() 
  2. >>> print article_view 
  3. 閱讀(6) 

很多人覺得 xpath 方法里的規(guī)則太過復(fù)雜。其實(shí)只要了解一點(diǎn) HTML 文件的 DOM 結(jié)構(gòu),掌握 xpath 的提取規(guī)則還是比較輕松容易的。好在 scrapy shell 允許我們反復(fù)對(duì) DOM 文件進(jìn)行嘗試解析。實(shí)驗(yàn)成功的 xpath 表達(dá)式就可以直接用在項(xiàng)目里了。

四、創(chuàng)建scrapy項(xiàng)目

scrapy shell 僅僅適用于測(cè)試目標(biāo)網(wǎng)站是否可以正常采集以及采集之后如何解析,真正做項(xiàng)目的時(shí)候還需要從頭建立一個(gè) scrapy 項(xiàng)目。 輸入以下命令退出 scrapy shell 并返回 Linux 命令行:

  1. >>> exit() 

假設(shè)我們的項(xiàng)目名稱叫 cnblogs_scrapy ,則可通過下面的命令來創(chuàng)建一個(gè) scrapy 項(xiàng)目:

  1. scrapy startproject cnblogs_scrapy 

會(huì)自動(dòng)生成如下結(jié)構(gòu)的目錄與文件:

  1. |– cnblogs_scrapy 
  2. |        |– __init__.py 
  3. |        |– items.py 
  4. |        |– middlewares.py 
  5. |        |– pipelines.py 
  6. |        |– settings.py 
  7. |        `– spiders 
  8. |                `– __init__.py 
  9. `– scrapy.cfg 

五、解析與存儲(chǔ)

我們需要改三個(gè)地方:

1. 在spiders目錄下建一個(gè)文件cnblogs_mysql.py

內(nèi)容如下:

  1. # -*- coding: utf-8 -*- 
  2.  
  3. import scrapy 
  4.  
  5. import sys 
  6. reload( sys ) 
  7. sys.setdefaultencoding( "utf8" ) 
  8.  
  9. class CnblogsMySQL(scrapy.Spider): 
  10.  
  11.     # 爬蟲的名字,必須有這個(gè)變量 
  12.     name = 'cnblogs_mysql' 
  13.      
  14.     page_index = 1 
  15.      
  16.     # 初始地址,必須有這個(gè)變量 
  17.     start_urls = [ 
  18.         'https://www.cnblogs.com/cate/mysql/' + str( page_index ), 
  19.     ] 
  20.      
  21.     def parse(self, response): 
  22.      
  23.         post_items = response.xpath(  
  24.             "//div[@id='wrapper']/div[@id='main']/div[@id='post_list']/div[@class='post_item']/div[@class='post_item_body']"  
  25.                 ) 
  26.                  
  27.         for post_item_body in post_items: 
  28.             yield { 
  29.                 'article_title':  
  30.                     post_item_body.xpath( "h3/a/text()" ).extract_first().strip(), 
  31.                 'article_summary':  
  32.                     post_item_body.xpath( "p[@class='post_item_summary']/text()" ).extract_first().strip(), 
  33.                 'post_date':  
  34.                     post_item_body.xpath( "div[@class='post_item_foot']/text()" ).extract()[ 1 ].strip(), 
  35.                 'article_view' :  
  36.                     post_item_body.xpath(  
  37.                             "div[@class='post_item_foot']/span[@class='article_view']/a/text()"  
  38.                         ).extract_first().strip() 
  39.             } 
  40.      
  41.         next_page_url = None 
  42.         self.page_index += 1 
  43.         if self.page_index <= 20: 
  44.             next_page_url = "https://www.cnblogs.com/cate/mysql/" + str( self.page_index ) 
  45.         else: 
  46.             next_page_url = None 
  47.      
  48.         if next_page_url is not None: 
  49.             yield scrapy.Request(response.urljoin(next_page_url)) 

這個(gè)就是我們的爬蟲,其中 name 和 start_urls 兩個(gè)變量必須存在。parse 方法的作用是將響應(yīng)內(nèi)容解析為我們需要的數(shù)據(jù)。parse 中的 for 循環(huán)就是在提取每一頁(yè)中的 20 篇文章。解析并提取完成后,通過 yield 將結(jié)果拋到 pipeline 進(jìn)行存儲(chǔ)。

2. 修改pipelines.py文件,內(nèi)容如下:

  1. # -*- coding: utf-8 -*- 
  2.  
  3. # Define your item pipelines here 
  4. # Don't forget to add your pipeline to the ITEM_PIPELINES setting 
  5. # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html 
  6.  
  7.  
  8. class CnblogsScrapyPipeline(object): 
  9.  
  10.     def open_spider( self, spider ): 
  11.  
  12.         self.fp = open( "data.list", "w" ) 
  13.  
  14.     def close_spider( self, spider ): 
  15.  
  16.         self.fp.close() 
  17.  
  18.     def process_item(self, item, spider): 
  19.  
  20.         self.fp.write( item[ "article_title" ] + "\n" ) 
  21.         self.fp.write( item[ "article_view" ] + "\n" ) 
  22.         self.fp.write( item[ "post_date" ] + "\n" ) 
  23.         self.fp.write( item[ "article_summary" ] + "\n\n" ) 
  24.  
  25.         return item 

可以看到有三個(gè)方法。這三個(gè)方法是從基類中繼承而來。open_spider/close_spider 分別在爬蟲啟動(dòng)和結(jié)束的時(shí)候執(zhí)行,一般用作初始化及收尾。process_item 會(huì)在每一次 spider 解析出數(shù)據(jù)后 yield 的時(shí)候執(zhí)行,用來處理解析的結(jié)果。上面這個(gè) pipeline 的作用是將每一條記錄都存儲(chǔ)到文件中。當(dāng)然也可以通過 pipeline 將內(nèi)容存儲(chǔ)到數(shù)據(jù)庫(kù)或其它地方。

3. 配置pipeline

注意僅僅有這個(gè) pipeline 文件還不能工作,需要在配置文件中向 scrapy 聲明 pipeline。同目錄下有個(gè) settings.py 文件,加入如下內(nèi)容:

  1. ITEM_PIPELINES = { 
  2.         'cnblogs_scrapy.pipelines.CnblogsScrapyPipeline': 300, 

后面的數(shù)字是 pipeline 的權(quán)重,如果一個(gè)爬蟲有多個(gè) pipeline,各個(gè) pipeline 的執(zhí)行順序由這個(gè)權(quán)重來決定。

修改完成并保存之后,退到 cnblogs_scrapy 的上層目錄,并輸入以下命令啟動(dòng)爬蟲:

  1. scrapy crawl cnblogs_mysql 

所有經(jīng)過處理的信息都會(huì)輸出到屏幕上。結(jié)束之后,當(dāng)前目錄中會(huì)生成名為 data.list 的文件,里面存儲(chǔ)了本次采集的所有數(shù)據(jù)。

六、翻頁(yè)

cnblogs_mysql.py 的 parse 方法中有個(gè) next_page_url 變量,一般情況下這個(gè)變量的內(nèi)容應(yīng)當(dāng)是當(dāng)前頁(yè)面的下一頁(yè) URL,該 URL 當(dāng)然也可以通過解析頁(yè)面來獲取。獲得下一頁(yè)的URL之后,用 scrapy.Request 來發(fā)起新一次的請(qǐng)求。 簡(jiǎn)單起見本文通過直接拼接 URL 的形式來指定僅采集前 20 頁(yè)的數(shù)據(jù)。

七、其它

用 scrapy 發(fā)請(qǐng)求之前,也可以自己構(gòu)造 Request,這樣就能偽裝為真實(shí)訪問來避免被封。一般情況下有修改 User-Agent、隨機(jī)采集時(shí)間、隨機(jī)代理 IP 等方法。 scrapy 項(xiàng)目可以直接運(yùn)行,也可以部署在云端進(jìn)行批量采集和監(jiān)控。云端部署需要用到 scrapyd,操作起來也很簡(jiǎn)單,有需要的話可自行參考官網(wǎng)文檔。

【本文是51CTO專欄機(jī)構(gòu)“豈安科技”的原創(chuàng)文章,轉(zhuǎn)載請(qǐng)通過微信公眾號(hào)(bigsec)聯(lián)系原作者】

戳這里,看該作者更多好文

責(zé)任編輯:趙寧寧 來源: 51CTO專欄
相關(guān)推薦

2023-11-29 10:16:24

ScrapyPython

2012-05-25 15:35:43

JMSJava

2015-07-23 10:54:09

Java Mybati框架

2009-06-18 09:29:44

Spring Web

2017-05-15 21:00:15

大數(shù)據(jù)Scrapy爬蟲框架

2018-08-08 11:40:24

ScrapyRequest網(wǎng)絡(luò)爬蟲

2013-08-27 13:44:49

2017-11-29 15:21:53

PythonScrapy爬蟲

2021-01-08 09:07:19

Scrapy框架爬蟲

2016-03-18 11:19:57

ios9replaykit入門

2020-10-27 08:33:38

Scrapy

2012-07-17 09:13:14

Scrapy

2020-12-07 11:23:32

Scrapy爬蟲Python

2021-11-09 09:46:09

ScrapyPython爬蟲

2021-11-08 14:38:50

框架Scrapy 爬蟲

2021-04-12 07:36:15

Scrapy爬蟲框架

2009-01-03 14:39:00

ibmdwSpirit

2018-05-16 13:50:30

Python網(wǎng)絡(luò)爬蟲Scrapy

2021-05-18 13:25:28

feapder爬蟲Python

2020-11-11 10:58:59

Scrapy
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)