爬蟲學習(二)

Scrapy使用和入門

1.創建一個scrapy項目

  • scrapy startproject myspider

在這裏插入圖片描述創建了一個名爲myspider的項目,生成了這麼些東西
在這裏插入圖片描述

2.生成一個爬蟲

  • cd myspider # 進入項目文件夾裏
  • scrapy genspider itcast itcast.cn

在這裏插入圖片描述
首先進入哪個爬蟲項目(可能有多個),然後生成了一個爬蟲,爬蟲名爲itcast,爬取的域名範圍是itcast.cn怕的就是這爬蟲爬的太快,爬到別的網站去了,所以限制一下

生成了這麼一個文件
在這裏插入圖片描述

這個文件主要就是處理響應信息,提取數據,我們可以寫如下程序,是請求某一個url,提取裏面某些數據

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


class ItcastSpider(scrapy.Spider):
    name = 'itcast'
    allowed_domains = ['itcast.cn']
    start_urls = ['http://www.itcast.cn/channel/teacher.shtml#ajavaee']

    def parse(self, response):
        # 處理start_url地址對應的響應
        ret = response.xpath("//div[@class='tea_con']//h3/text()")
        print(ret)

然後我們啓動這個爬蟲 scrapy crawl itcast

注意要在項目文件夾下運行,後面一個是爬蟲的名字
在這裏插入圖片描述

看看結果,除了我們需要打印的東西,還要好多亂七八糟的東西,這些其實是日誌
在這裏插入圖片描述

打印這麼多日誌,看起來非常麻煩,我們可以設置一下,在settings.py中添加一行語句

LOG_LEVEL = "WARNING"

現在運行的時候,除了打印我們想要的信息,只會顯示WARNING及等級以上的信息,比如WARNING和WRONG

我們從上面打印中,還發現,這是一個對象,我們可以提取裏面的數據,使用.extract()方法

    def parse(self, response):
        # 處理start_url地址對應的響應
        ret = response.xpath("//div[@class='tea_con']//h3/text()").extract()
        print(ret)

在這裏插入圖片描述

我們還可以像以前一樣進行分組寫

    def parse(self, response):
        # 處理start_url地址對應的響應
        # ret = response.xpath("//div[@class='tea_con']//h3/text()").extract()
        # print(ret)

        # 分組
        li_list = response.xpath("//div[@class='tea_con']//li")
        for li in li_list:
            item = {}
            item["name"] = li.xpath(".//h3/text()").extract()[0]
            item["title"] = li.xpath(".//h4/text()").extract()[0]
            print(item)

在這裏插入圖片描述
如果但是這樣寫,有時會出現錯誤,比如某一個字段裏面沒有值,因爲去了第0個,所以會報錯

其實還有更好的方法,也不用判斷它的長度是否大於0,它提供了.extract_first()方法

這個方法的好處在於,當不存在某個字段的時候,會自動填充None

class ItcastSpider(scrapy.Spider):
    name = 'itcast'
    allowed_domains = ['itcast.cn']
    start_urls = ['http://www.itcast.cn/channel/teacher.shtml#ajavaee']

    def parse(self, response):
        # 處理start_url地址對應的響應
        # ret = response.xpath("//div[@class='tea_con']//h3/text()").extract()
        # print(ret)

        # 分組
        li_list = response.xpath("//div[@class='tea_con']//li")
        for li in li_list:
            item = {}
            item["name"] = li.xpath(".//h3/text()").extract_first()
            item["title"] = li.xpath(".//h4/text()").extract_first()
            print(item)

接下來,我們看看如果將獲取的數據放進pipline裏面,pipline主要實現保存數據

使用yield可以將數據傳到pipline裏面,(可以返回一個字典,但是不能返回列表)

    def parse(self, response):
        # 處理start_url地址對應的響應
        # ret = response.xpath("//div[@class='tea_con']//h3/text()").extract()
        # print(ret)

        # 分組
        li_list = response.xpath("//div[@class='tea_con']//li")
        for li in li_list:
            item = {}
            item["name"] = li.xpath(".//h3/text()").extract_first()
            item["title"] = li.xpath(".//h4/text()").extract_first()
            # print(item)
            yield item

當然,scrapy模式是關閉pipline的,我們需要將它開啓

settings.py中,我們需要作如下操作,將這些部分取消註釋就好了

圖中的300是權重,值越小先執行,因爲可以存在多個pipline
在這裏插入圖片描述

piplines.py中,我們可以打印數據

class MyspiderPipeline(object):
    def process_item(self, item, spider):
        print(item)
        return item

pipline介紹

當存在多個爬蟲,pipline怎麼能確定這數據是來自與哪一個爬蟲的呢?

pipline裏面的函數還有一個參數,當爬蟲傳遞數據過來,會指名是哪個爬蟲傳過來的

class MyspiderPipeline(object):
    def process_item(self, item, spider):
        if spider.name == 'itcast':
            print(item)
        return item

logging模塊的使用

它可以幫助生成日誌

# -*- coding: utf-8 -*-
import scrapy
import logging

logger = logging.getLogger(__name__)

class ItcastSpider(scrapy.Spider):
    name = 'itcast'
    allowed_domains = ['itcast.cn']
    start_urls = ['http://itcast.cn/']

    def parse(self, response):
        for i in range(10):
            item = {}
            item["com_from"] = "itcast"
            logger.warning(item)

導入模塊,生成實例,調用,打印如下,可以看出哪個文件打印出來的日誌

在這裏插入圖片描述


還可以將日誌保存到本地

settings.py裏添加如下語句

LOG_FILE = './log.log'   # 文件路徑

這時候,日誌都保存到這個文件裏面,而終端不會顯示

構造request請求

我們如何請求下一頁呢?或者又是別的url?

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


class ItcastSpider(scrapy.Spider):
    name = 'itcast'
    allowed_domains = ['itcast.cn']
    start_urls = ['http://itcast.cn/']

    def parse(self, response):
        '''
        do something
        '''
        # 通過一系列操作獲取到url
        next_url = "http://www.xxx.com"
        yield scrapy.Request(
            next_url,
            callback=self.parse
        )

還可以帶其他的參數
在這裏插入圖片描述
cookie和headers是分開的
callback可以指向另一個parse函數,不一定是本身
還可以實現參數的傳遞

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


class ItcastSpider(scrapy.Spider):
    name = 'itcast'
    allowed_domains = ['itcast.cn']
    start_urls = ['http://itcast.cn/']

    def parse(self, response):
        '''
        do something
        '''
        item = {}
        item["title"] = "xxx"
        item["href"] = "xxx"
        yield item
        # 通過一系列操作獲取到url
        next_url = "http://www.xxx.com"
        yield scrapy.Request(
            next_url,
            callback=self.parse1,
            meta = {"item":item }
        )

    def parse1(self, response):
        response.meta["item"]  # 獲取上面的item

小練習,爬取騰訊的某網站

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


class HrSpider(scrapy.Spider):
    name = 'hr'
    allowed_domains = ['tencent.com']
    start_urls = ['http://hr.tencent.com/position.php']

    def parse(self, response):
        tr_list = response.xpath("//table[@class='tablelist']/tr")[1:-1]
        for tr in tr_list:
            item = {}
            item["title"] = tr.xpath("./td[1]/a/text()").extract_first()
            item["position"] = tr.xpath("./td[2]/text()").extract_first()
            item["publish_date"] = tr.xpath("./td[5]/a/text()").extract_first()
            yield item
        # 找到下一頁的url
        next_url= response.xpath("//a[@id='next'/@href]").extract_first()
        if next_url != "javascript":
            yield scrapy.Request(
                next_url,
                callback=self.parse  # 下一頁處理方式一樣,所以返給自己
                # 如果處理方式不一樣,可以另外寫一個回調函數
            )
            

設置User-Agent

setting.py文件裏,註銷這麼條語句,換取自己的User-Agent

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章