爬蟲之Scrapy安裝及簡單使用(macOS)

1.前提

1.1 使用Mac OS系統(tǒng)
1.2 Python3.x版本
1.3 因?yàn)閙ac系統(tǒng)自帶python2.7,因此必須在終端將版本修改為python3.x版本

終端執(zhí)行:

$sudo vim ~/.bash_profile

在bash_profile文件中增加下面的語句,需要安裝python3時(shí)的路徑:

alias python='/Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6’

終端執(zhí)行,使之生效:

$source ~/.bash_profile

2.安裝Scrapy

Python3.6.5安裝包中默認(rèn)帶有pip3命令,直接使用即可。

$pip3 install scrapy

注意:如果使用了pip install scrapy,則安裝的scrapy將會默認(rèn)搜索python2.7相關(guān)文件。這會在我們運(yùn)行測試的時(shí)候報(bào)錯(cuò),因?yàn)槲覀兯械恼Z法和scrapy都是基于python3.x的!

終端應(yīng)該輸入以下內(nèi)容:

$pip3 install scrapy
Collecting scrapy
  Downloading https://files.pythonhosted.org/packages/5d/12/a6197eaf97385e96fd8ec56627749a6229a9b3178ad73866a0b1fb377379/Scrapy-1.5.1-py2.py3-none-any.whl (249kB)
    100% |████████████████████████████████| 256kB 600kB/s 
Collecting pyOpenSSL (from scrapy)
  Downloading https://files.pythonhosted.org/packages/96/af/9d29e6bd40823061aea2e0574ccb2fcf72bfd6130ce53d32773ec375458c/pyOpenSSL-18.0.0-py2.py3-none-any.whl (53kB)
    100% |████████████████████████████████| 61kB 17.5MB/s 
Collecting cssselect>=0.9 (from scrapy)
  Downloading https://files.pythonhosted.org/packages/7b/44/25b7283e50585f0b4156960691d951b05d061abf4a714078393e51929b30/cssselect-1.0.3-py2.py3-none-any.whl
Collecting service-identity (from scrapy)
.
.
.
Successfully installed Automat-0.7.0 PyDispatcher-2.0.5 PyHamcrest-1.9.0 Twisted-18.9.0 asn1crypto-0.24.0 attrs-18.2.0 cffi-1.11.5 constantly-15.1.0 cryptography-2.3.1 cssselect-1.0.3 enum34-1.1.6 functools32-3.2.3.post2 hyperlink-18.0.0 idna-2.7 incremental-17.5.0 ipaddress-1.0.22 lxml-4.2.5 parsel-1.5.0 pyOpenSSL-18.0.0 pyasn1-0.4.4 pyasn1-modules-0.2.2 pycparser-2.19 queuelib-1.5.0 scrapy-1.5.1 service-identity-17.0.0 six-1.11.0 w3lib-1.19.0 zope.interface-4.5.0

默認(rèn)同時(shí)安裝了幾個(gè)Scrapy需要依賴的包。

3.查看Scrapy

$Scrapy version
Scrapy 1.5.1

這里安裝的是1.5.1版本

which Scrapy
/Library/Frameworks/Python.framework/Versions/3.6/bin/scrapy

這是安裝的路徑。

如果使用的是pip install scrapy,則scrapy的路徑為/usr/local/bin/scrapy,默認(rèn)會查找python2.7版本的包,使我們的測試失敗。因?yàn)槲覀冞@里使用python3,因此這點(diǎn)需要特別注意。

4.創(chuàng)建Scrapy項(xiàng)目

在桌面創(chuàng)建了一個(gè)Demo工程

$cd Desktop
$scrapy startproject Demo

scrapy startproject:創(chuàng)建一個(gè)scrapy項(xiàng)目。

以下是項(xiàng)目的目錄結(jié)構(gòu):

Demo/
    scrapy.cfg
    Demo/
        __init__.py
        items.py
        pipelines.py
        settings.py
        middlewares.py
        spiders/
                __init__.py
                ......

5.編寫代碼

使用Scrapy抓取一個(gè)網(wǎng)站需要四個(gè)步驟:

  1. 創(chuàng)建一個(gè)Scrapy項(xiàng)目
  2. 定義Item容器
  3. 編寫爬蟲
  4. 存儲內(nèi)容
5.1 設(shè)置抓取網(wǎng)站并建模

這里我們采用http://www.n#網(wǎng)站的站點(diǎn)資訊資源:

97D6A079-CC2F-41AE-B50C-F42D9AA27D8B.png

我們需要抓取的是該板塊的標(biāo)題鏈接

在項(xiàng)目中,我們在items.py文件中建立相應(yīng)的字段:

import scrapy
class DemoItem(scrapy.Item):
  #define the fields for you item here like:
  #name = scrapy.Field()
  title = scrapy.Field() #抓取的標(biāo)題
  link = scrapy.Field() #抓取的鏈接
5.2 編寫爬蟲

在項(xiàng)目的Spider目錄中,創(chuàng)建名為DemoSprider.py的文件,編寫爬蟲代碼:

import scrapy

class DemoSpider(scrapy.Spider):
    # name表示爬蟲的名字,在`scrapy crawl xx`時(shí)使用
    name = “demo”
    # allowed_domains定義了爬取的范圍,限定在某幾個(gè)域名內(nèi)
    allowed_domains = ['http://www.n#’]
    # start_urls定義了從哪里開始爬取
    start_urls = ['http://www.n#’]

    # parse方法用于接收Downloader返回的結(jié)果
    def parse(self,response):
        with open('homepage','wb') as f:
            f.write(response.body)

這里我們接收到爬取的內(nèi)容后,先寫入到文件homepage中,模擬爬的過程,查看是否正確。

5.3 運(yùn)行爬蟲,使用終端調(diào)試
# 進(jìn)入第二層的Demo目錄內(nèi)
$cd ~/Desktop/Demo/Demo
# 這里的demo即是我們在DemoSpider.py文件中設(shè)置的name屬性
$scrapy crawl demo 

會在Demo文件夾下生成一個(gè)homepage文件,使用文本打開,會發(fā)現(xiàn)這就是該網(wǎng)站的html代碼。

6.scrapy的xpath語法

抓取到html后,我們需要對html內(nèi)容進(jìn)行分析,傳統(tǒng)方式是使用正則表達(dá)式。scrapy提供了幾個(gè)方法,可以簡化我們的操作,使查詢更容易。
下面是一些基本語法:

語法 含義
/html/head/title 選擇HTML文檔中<head>標(biāo)簽內(nèi)的<title>元素
/html/head/title/text() 選擇上面提到的title元素的文本
//td 選擇所有的<td>元素
//div[@class='mine'] 選擇所有具有class='mine'屬性的div元素
6.1 測試xpath語法
# 終端輸入,進(jìn)入scrapy shell模式
$scrapy shell "http://www.n#”
# 反饋
2018-10-16 17:04:58 [scrapy.utils.log] INFO: Scrapy 1.5.1 started (bot: scrapybot)
2018-10-16 17:04:58 [scrapy.utils.log] INFO: Versions: lxml 4.2.5.0, libxml2 2.9.8, cssselect 1.0.3, parsel 1.5.0, w3lib 1.19.0, Twisted 18.9.0, Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 03:03:55) - [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)], pyOpenSSL 18.0.0 (OpenSSL 1.1.0i  14 Aug 2018), cryptography 2.3.1, Platform Darwin-17.5.0-x86_64-i386-64bit
2018-10-16 17:04:58 [scrapy.crawler] INFO: Overridden settings: {'DUPEFILTER_CLASS': 'scrapy.dupefilters.BaseDupeFilter', 'LOGSTATS_INTERVAL': 0}
2018-10-16 17:04:58 [scrapy.middleware] INFO: Enabled extensions:
[‘scrapy.extensions.corestats.CoreStats’,
 ‘scrapy.extensions.telnet.TelnetConsole’,
 ‘scrapy.extensions.memusage.MemoryUsage’]
.
.
.
>>>

進(jìn)入該模式后,scrapy Engine會返回給我們一個(gè)response回應(yīng),可以用它查看網(wǎng)頁信息:

>>> response.headers
{b'Server': [b'nginx'], b'Date': [b'Tue, 16 Oct 2018 09:05:56 GMT'], b'Content-Type': [b'text/html; charset=utf-8'], b'Vary': [b'Accept-Encoding'], b'X-Powered-By': [b'PHP/5.3.29'], b'Set-Cookie': [b'PHPSESSID=nd3665jsfcp0cn7b5poc2qcfg3; path=/'], b'Content-Security-Policy': [b'upgrade-insecure-requests’]}
>>>

查詢所有title:

>>> response.xpath('//title’)
[<Selector xpath='//title' data='<title>\n\n            分類目錄網(wǎng)-網(wǎng)站分類目錄大全,好用的網(wǎng)’>]
>>> 

注意,這里返回的是Selector對象,如果想得到字符串,可以使用extract()方法,extract()方法會將Selector對象轉(zhuǎn)化為列表對象:

>>> response.xpath('//title').extract()
['<title>\n\n            分類目錄網(wǎng)-網(wǎng)站分類目錄大全,好用的網(wǎng)站導(dǎo)航\n\n        </title>’]
>>> 

這里返回的是文本列表。
如果想得到title標(biāo)簽的文本內(nèi)容,可以使用下面的語法:

>>> response.xpath('//title/text()').extract()
['\n\n            分類目錄網(wǎng)-網(wǎng)站分類目錄大全,好用的網(wǎng)站導(dǎo)航\n\n        ‘]
>>> 
6.2 抓取我們的目標(biāo)

通過瀏覽器自帶的審查元素,我們知道需要的站點(diǎn)資訊ul元素的class屬性為newslist,并且頁面內(nèi)沒有其他與其重復(fù),因此這可以作為關(guān)鍵點(diǎn)來抓取。

EE43F12C-91A7-4832-A63E-C2334962044E.png

>>> response.xpath("http://ul[@class='newslist']").extract()
['<ul class="newslist">\n\n                                \n\t\t\t\t\t\t<li>\n\n\t\t\t\t\t\t<span>\n\n                                        2018-10-09\n\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<a href="/artinfo/1800.html">\n\n                                        工業(yè)門的門洞要求及生產(chǎn)工藝[轉(zhuǎn)載]\n\n\t\t\t\t\t\t</a>\n\n\t\t\t\t\t\t</li>\n\n                                \n\t\t\t\t\t\t<li>\n\n\t\t\t\t\t\t<span>\n\n                                        2018-10-09\n\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<a href="/artinfo/1799.html">\n\n                                        健康公益中原行啟動(dòng)儀式在鄭州成功舉辦\n\n\t\t\t\t\t\t</a>\n\n\t\t\t\t\t\t</li>\n\n                                \n\t\t\t\t\t\t<li>\n\n\t\t\t\t\t\t<span>\n\n                                        2018-10-08\n\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<a href="/artinfo/1798.html">\n\n                                        區(qū)塊鏈?zhǔn)鞘裁??區(qū)塊鏈+電商怎么落地呢??\n\n\t\t\t\t\t\t</a>\n\n\t\t\t\t\t\t</li>\n\n                                \n\t\t\t\t\t\t<li>\n\n\t\t\t\t\t\t<span>\n\n                                        2018-10-07\n\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<a href="/artinfo/1796.html">\n\n                                        簡述工業(yè)門的操控方式及安全性能[轉(zhuǎn)載]\n\n\t\t\t\t\t\t</a>\n\n\t\t\t\t\t\t</li>\n\n                                \n\t\t\t\t\t\t<li>\n\n\t\t\t\t\t\t<span>\n\n                                        2018-09-29\n\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<a href="/artinfo/1791.html">\n\n                                        西安格帆“照明空氣凈化器”面向全國招商\n\n\t\t\t\t\t\t</a>\n\n\t\t\t\t\t\t</li>\n\n                                \n\t\t\t\t\t\t<li>\n\n\t\t\t\t\t\t<span>\n\n                                        2018-09-27\n\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<a href="/artinfo/1787.html">\n\n                                        區(qū)塊鏈?zhǔn)鞘裁矗繀^(qū)塊鏈+電商怎么落地呢?\n\n\t\t\t\t\t\t</a>\n\n\t\t\t\t\t\t</li>\n\n                                \n\t\t\t\t\t\t<li>\n\n\t\t\t\t\t\t<span>\n\n                                        2018-09-27\n\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<a href="/artinfo/1786.html">\n\n                                        2018有哪些免費(fèi)收錄的分類目錄站點(diǎn)\n\n\t\t\t\t\t\t</a>\n\n\t\t\t\t\t\t</li>\n\n                                \n\t\t\t\t\t\t<li>\n\n\t\t\t\t\t\t<span>\n\n                                        2018-09-27\n\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<a href="/artinfo/1785.html">\n\n                                        分類目錄網(wǎng)站外鏈還有效果嗎?\n\n\t\t\t\t\t\t</a>\n\n\t\t\t\t\t\t</li>\n\n                                \n\t\t\t\t\t\t<li>\n\n\t\t\t\t\t\t<span>\n\n                                        2018-09-27\n\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<a href="/artinfo/1783.html">\n\n                                        想做點(diǎn)小生意,coco奶茶加盟不好做?\n\n\t\t\t\t\t\t</a>\n\n\t\t\t\t\t\t</li>\n\n                                \n\t\t\t\t\t\t<li>\n\n\t\t\t\t\t\t<span>\n\n                                        2018-09-25\n\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<a href="/artinfo/1775.html">\n\n                                        傳統(tǒng)行業(yè)如何向互聯(lián)網(wǎng)轉(zhuǎn)型?\n\n\t\t\t\t\t\t</a>\n\n\t\t\t\t\t\t</li>\n\n                                \n\t\t\t\t\t\t<li>\n\n\t\t\t\t\t\t<span>\n\n                                        2018-09-25\n\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<a href="/artinfo/1774.html">\n\n                                        CentOS7開放關(guān)閉防火墻與端口\n\n\t\t\t\t\t\t</a>\n\n\t\t\t\t\t\t</li>\n\n                                \n\t\t\t\t\t\t<li>\n\n\t\t\t\t\t\t<span>\n\n                                        2018-09-24\n\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<a href="/artinfo/1772.html">\n\n                                        通過 CSP 指令解決https加載不了http資源問題\n\n\t\t\t\t\t\t</a>\n\n\t\t\t\t\t\t</li>\n\n                                \n\t\t\t\t\t\t<li>\n\n\t\t\t\t\t\t<span>\n\n                                        2018-09-21\n\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<a href="/artinfo/1767.html">\n\n                                        區(qū)塊鏈+電商平臺設(shè)計(jì)\n\n\t\t\t\t\t\t</a>\n\n\t\t\t\t\t\t</li>\n\n                                \n\t\t\t\t\t\t<li>\n\n\t\t\t\t\t\t<span>\n\n                                        2018-09-17\n\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<a href="/artinfo/1755.html">\n\n                                        windows重裝系統(tǒng)備份還原用戶憑據(jù)方法\n\n\t\t\t\t\t\t</a>\n\n\t\t\t\t\t\t</li>\n\n                                \n\t\t\t\t\t\t<li>\n\n\t\t\t\t\t\t<span>\n\n                                        2018-09-14\n\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<a href="/artinfo/1752.html">\n\n                                        CentOS 7雙網(wǎng)卡雙IP內(nèi)外網(wǎng)關(guān)配置\n\n\t\t\t\t\t\t</a>\n\n\t\t\t\t\t\t</li>\n\n                                \n\t\t\t\t\t\t<li>\n\n\t\t\t\t\t\t<span>\n\n                                        2018-09-05\n\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<a href="/artinfo/1733.html">\n\n                                        linux vps修改時(shí)區(qū)設(shè)置\n\n\t\t\t\t\t\t</a>\n\n\t\t\t\t\t\t</li>\n\n                                \n\t\t\t\t\t\t<li>\n\n\t\t\t\t\t\t<span>\n\n                                        2018-09-03\n\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<a href="/artinfo/1729.html">\n\n                                        postgresql 創(chuàng)建數(shù)據(jù)庫 ERROR: new encoding (UTF8) is incompatible\n\n\t\t\t\t\t\t</a>\n\n\t\t\t\t\t\t</li>\n\n                                \n\t\t\t\t\t\t<li>\n\n\t\t\t\t\t\t<span>\n\n                                        2018-08-31\n\n\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t<a href="/artinfo/1724.html">\n\n                                        為什么工業(yè)門要設(shè)置平衡系統(tǒng)?[轉(zhuǎn)載]\n\n\t\t\t\t\t\t</a>\n\n\t\t\t\t\t\t</li>\n\n                                \n\t\t\t\t\t</ul>’]
>>> 

可以看到,抓到了我們想要的結(jié)果。

6.3 提取title和link
# 獲取Selector對象列表,找到所有l(wèi)i元素的Selector對象
>>> sites = response.xpath('//ul[@class="newslist"]/li’)
>>> for site in sites:
...     title = site.xpath('a/text()').extract()
...     print(title)
... 
['\n\n                                        工業(yè)門的門洞要求及生產(chǎn)工藝[轉(zhuǎn)載]\n\n\t\t\t\t\t\t’]
['\n\n                                        健康公益中原行啟動(dòng)儀式在鄭州成功舉辦\n\n\t\t\t\t\t\t’]
['\n\n                                        區(qū)塊鏈?zhǔn)鞘裁??區(qū)塊鏈+電商怎么落地呢??\n\n\t\t\t\t\t\t’]
['\n\n                                        簡述工業(yè)門的操控方式及安全性能[轉(zhuǎn)載]\n\n\t\t\t\t\t\t’]
['\n\n                                        西安格帆“照明空氣凈化器”面向全國招商\n\n\t\t\t\t\t\t’]
['\n\n                                        區(qū)塊鏈?zhǔn)鞘裁矗繀^(qū)塊鏈+電商怎么落地呢?\n\n\t\t\t\t\t\t’]
['\n\n                                        2018有哪些免費(fèi)收錄的分類目錄站點(diǎn)\n\n\t\t\t\t\t\t’]
['\n\n                                        分類目錄網(wǎng)站外鏈還有效果嗎?\n\n\t\t\t\t\t\t’]
['\n\n                                        想做點(diǎn)小生意,coco奶茶加盟不好做?\n\n\t\t\t\t\t\t’]
['\n\n                                        傳統(tǒng)行業(yè)如何向互聯(lián)網(wǎng)轉(zhuǎn)型?\n\n\t\t\t\t\t\t’]
['\n\n                                        CentOS7開放關(guān)閉防火墻與端口\n\n\t\t\t\t\t\t’]
['\n\n                                        通過 CSP 指令解決https加載不了http資源問題\n\n\t\t\t\t\t\t’]
['\n\n                                        區(qū)塊鏈+電商平臺設(shè)計(jì)\n\n\t\t\t\t\t\t’]
['\n\n                                        windows重裝系統(tǒng)備份還原用戶憑據(jù)方法\n\n\t\t\t\t\t\t’]
['\n\n                                        CentOS 7雙網(wǎng)卡雙IP內(nèi)外網(wǎng)關(guān)配置\n\n\t\t\t\t\t\t’]
['\n\n                                        linux vps修改時(shí)區(qū)設(shè)置\n\n\t\t\t\t\t\t’]
['\n\n                                        postgresql 創(chuàng)建數(shù)據(jù)庫 ERROR: new encoding (UTF8) is incompatible\n\n\t\t\t\t\t\t’]
['\n\n                                        為什么工業(yè)門要設(shè)置平衡系統(tǒng)?[轉(zhuǎn)載]\n\n\t\t\t\t\t\t’]
>>> 

可以看到,獲取了所有標(biāo)題。

>>> for site in sites:
...     link = site.xpath('a/@href').extract()
...     print(link)
... 
['/artinfo/1800.html’]
['/artinfo/1799.html’]
['/artinfo/1798.html’]
['/artinfo/1796.html’]
['/artinfo/1791.html’]
['/artinfo/1787.html’]
['/artinfo/1786.html’]
['/artinfo/1785.html’]
['/artinfo/1783.html’]
['/artinfo/1775.html’]
['/artinfo/1774.html’]
['/artinfo/1772.html’]
['/artinfo/1767.html’]
['/artinfo/1755.html’]
['/artinfo/1752.html’]
['/artinfo/1733.html’]
['/artinfo/1729.html’]
['/artinfo/1724.html’]
>>> 

獲取了所有鏈接。不過,這些鏈接都是相對路徑,到代碼中我們需要拼接域名。

7.代碼實(shí)現(xiàn)

代碼實(shí)現(xiàn)的過程,其實(shí)就是將我們在終端中的命令用代碼實(shí)現(xiàn)一遍。

def parse(self,response):
        sites = response.xpath("http://ul[@class='newslist']/li")
        for site in sites:
            title = site.xpath('a/text()').extract()
            link = site.xpath('a/@href').extract()
            print(title,link)
06D2FC39-7DCB-4158-992C-16FF7B2DE543.png

8.導(dǎo)入item模塊


import scrapy
from Demo.items import DemoItem 

class DemoSpider(scrapy.Spider):
    # name表示爬蟲的名字,在`scrapy crawl xx`時(shí)使用
    name = "demo"
    # allowed_domains定義了爬取的范圍,限定在某幾個(gè)域名內(nèi)
    allowed_domains = ['http://www.n#']
    # start_urls定義了從哪里開始爬取
    start_urls = ['http://www.n#']

    # parse方法用于接受Downloader返回的結(jié)果
    def parse(self,response):
        sites = response.xpath("http://ul[@class='newslist']/li")
        items = []
        for site in sites:
            item = DemoItem()
            item['title'] = site.xpath('a/text()').extract()[0]
            item['link'] = self.allowed_domains[0] + site.xpath('a/@href').extract()[0]
            items.append(item)
        return items

8.導(dǎo)出抓取結(jié)果

# 將parse函數(shù)返回的結(jié)果進(jìn)行導(dǎo)出,使用json格式
$scrapy crawl demo -o items.json -t json

如果沒有意外,可以看到Demo文件夾下面多了item.json文件,里面就是我們需要抓取的內(nèi)容。

屏幕快照 2018-10-16 下午6.08.19.png

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容