天天看點

python爬蟲架構Scrapy安裝與爬取示例

環境:python3.6,自帶pip

# 安裝
pip install scrapy           

自動下載下傳所需元件

Installing collected packages: lxml, cssselect, six, w3lib, parsel, pyasn1, attrs, idna, asn1crypto, pycparser, cffi, cryptography, pyOpenSSL, pyasn1-modules,
service-identity, zope.interface, constantly, incremental, Automat, hyperlink, Twisted, queuelib, PyDispatcher, Scrapy           

安裝出現報錯提示

running build_ext
building 'twisted.test.raiser' extension
error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools           

下面開始我解決問題的曆程

我到http://landinghub.visualstudio.com/visual-cpp-build-tools下載下傳并安裝了Microsoft Visual C++ Build Tools(未完全安裝),pip install scrapy,再次報錯:

error: command 'cl.exe' failed: No such file or directory           

于是我分析了一下目前的狀态:scrapy沒有安裝成功,但scrapy所需的元件都下載下傳成功,包括twisted;隻是成功安裝了部分元件;在安裝twisted這個元件的過程中出了錯,是以twisted沒有安裝成功,安裝scrapy就卡在了這一步;twisted是一個C++編寫的庫,需要visual C++的環境去編譯;

1、第二個問題如何解決,我猜測應該是Microsoft Visual C++ Build Tools元件安裝少了(我在安裝它的時候在沒有完全安裝成功的狀态下就取消,因為我C槽快爆了,隻安裝了52個元件);重新解除安裝安裝?然後我沒有那麼做,空間占用太大,而且52個元件我能用到有幾個,我又不做C/C++開發;

2、看看第一個問題有沒有其他解決途徑

網上給出了第一個問題的第二種解決途徑,通路https://www.lfd.uci.edu/~gohlke/pythonlibs/,下載下傳與安裝python和系統位數對應的whl檔案,這個檔案很小;我的環境是python3.6和win64,是以下載下傳Twisted‑17.9.0‑cp36‑cp36m‑win_amd64.whl,在檔案所在位置打開指令行視窗,執行:pip install Twisted-17.9.0-cp36-cp36m-win_amd64.whl

Installing collected packages: Twisted
Successfully installed Twisted-17.9.0

# 該提示資訊表示Twisted安裝成功,再次安裝scrapy
pip install scrapy

# 最後兩行日志,scrapy安裝成功
Installing collected packages:quequelib,scrapy
Successfully installed queuelib-1.4.2 scrapy-1.4.0

# 檢視版本
scrapy
Scrapy 1.4.0 - no active project
···

# 解除安裝Microsoft Visual C++ Build
# 檢視安裝元件
pip list           

若在爬取的過程中出現如下錯誤,最好不要網上給的方法去下載下傳可執行檔案exe,下面一行代碼搞定

File "c:\users\administrator\appdata\local\programs\python\python36\lib\site-packages\twisted\internet\_win32stdio.py", line 9, in <module>
import win32api
ModuleNotFoundError: No module named 'win32api'

# 安裝pypiwin32
pip install pypiwin32           

scrapydemo

目标網址:http://www.seu.edu.cn/138/list.htm

1、建立項目

scrapy startproject scrapydemo           

2、建立scrapydemo\scrapydemo\spiders\ActivityItem.py

import scrapy


class ActivityItem(scrapy.Item):
    title = scrapy.Field()
    time = scrapy.Field()
    url = scrapy.Field()           

3、建立scrapydemo\scrapydemo\spiders\demo.py,使用xpath過濾資料

這裡需要三個變量:name 、allowed_domains 、start_urls 、和重寫Spider的parser函數,其中allowed_domains可省略;

from scrapy.spider import Spider
from scrapy.selector import Selector

from scrapydemo.spiders.ActivityItem import ActivityItem


class Demo2Spider(Spider):
    name = "demo"
    # allowed_domains = ["www.seu.edu.cn"]
    start_urls = [
        'http://www.seu.edu.cn/138/list.htm',
    ]

    def parse(self, response):

        content = response.body.decode("utf-8", "ignore")
        # Spider.log(self, "Open home page \n\n" + content)
        sel = Selector(response)
        sites = sel.xpath('//*[@id="wp_news_w6"]/ul/li')

        # fo = open("index.html", "w")
        # fo.write(content)
        # Spider.log(self, "\n檔案寫入完成... ")

        print(len(sites))
        items = []
        for site in sites:
            item = ActivityItem()
            print("\n")
            print(site.xpath('span/a/text()').extract())
            item['title'] = site.xpath('span/a/text()').extract()

            print(site.xpath('span/a/@href').extract())
            item['url'] = site.xpath('span/a/@href').extract()

            print(site.xpath('span/text()').extract())
            item['time'] = site.xpath('span/text()').extract()

            items.append(item)

        # 此處可省略,但後面寫入檔案或資料庫等操作會用到
        return items           

4、啟動爬蟲

scrapy crawl demo           

5、将爬取結果寫入檔案,會在工程根目錄下生産demo.json檔案

scrapy crawl demo -o demo.json           

若json檔案文本中文出現unicode編碼

# json檔案中文為unicode編碼解決辦法
scrapy crawl demo -o demo.json -s FEED_EXPORT_ENCODING=utf-8           

6、debug 調試

先在demo.py中打上斷點、然後在settings的同級目錄下建立run.py

# -*- coding: utf-8 -*-  
from scrapy import cmdline  

name = 'demo'  
cmd = 'scrapy crawl {0}'.format(name)  
cmdline.execute(cmd.split())           

右鍵->Debug Run,程式就會在斷點處停止;

7、爬取目标連結的所有資訊

目标連結是一個分頁連結,如果想爬取下一頁,下下一頁或者所有資訊是不是都要重寫一個爬蟲呢?scrapy架構為我們提供了簡便的方法,隻需要在demo.py中添加如下代碼:

next = response.xpath('//*[@id="wp_paging_w6"]/ul/li[2]/a[3]/@href').extract()
url = response.urljoin(next[0])
print(url)
yield scrapy.Request(url=url, callback=self.parse)           

爬取下一個的url,并執行回調函數parse,使用遞歸的方式,将爬取的資訊不斷地添加到items清單中,注意代碼不要加到for循環中哦