Python爬蟲學習(三)使用Scrapy庫


(一)Scrapy庫概述

  1,安裝:pip  install  scrapy失敗;

      運行D:\Python\Python36\python.exe -m pip install --upgrade pip命令升級pip命令失敗;

      修改Python36文件的權限:https://www.cnblogs.com/liaojiafa/p/5100550.html

      安裝:D:\Python\Python36\python.exe -m pip install wheel

      安裝:D:\Python\Python36\python.exe -m pip install scrapy

  2,框架概述:

    

    

     

     入口:SPIDERS;出口:ITEM  PIPELINES;用戶編寫SPIDERS(URL),ITEM  PIPELINES(對數據處理)

    ENGINE:控制所有模塊之間的數據流,根據條件觸發事件,不允許用戶修改,代碼已實現

    DOWNLOADER:根據請求下載網頁,功能單一,不允許用戶修改,代碼已實現

    SCHEDULER:對所有爬取請求進行調度管理,不允許用戶修改,代碼已實現

    DOWNLOADER  MIDDLEWARE:用戶可以修改配置;中間件

      

    SPIDERS:解析DOWNLOADER返回的響應(Response);產生爬取項(scraped  item);產生額外的爬取請求(Request);需要用戶編寫的最核心代碼

     ITEM  PIPELINES:以流水線方式處理Spider產生的爬取項;由一組操作順序組成,每個操作是一個item  pipelines類型;操作可包括:清理,檢驗,查重爬蟲項中HTML數據

將數據存入數據庫;由用戶編寫功能

    SPIDER  MIDDLEWARE:中間件

      

   3,requests庫和Scrapy庫區別:

    

     

     

 (二)Scrapy庫的使用

  1,Scrapy命令行:常用命令:創建過程,創建爬蟲,運行爬蟲為最常用命令

    

   2,爬取某個HTML:

    (1)建立過程: scrapy startproject python123demo

      

 

     (2)建立爬蟲demo:scrapy genspider demo python123.io;建立demo.py文件

#demo.py
# -*- coding: utf-8 -*-
import scrapy


class DemoSpider(scrapy.Spider):
    name = 'demo'
    allowed_domains = ['python123.io']          #說明只能爬取這個文件下的URL
    start_urls = ['http://python123.io/']

    def parse(self, response):              #處理響應,解析內容形成字典,發現新的URL爬取請求
        pass

    (3),修改爬蟲文件deom.py文件

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


class DemoSpider(scrapy.Spider):
    name = 'demo'
#    allowed_domains = ['python123.io']          #說明只能爬取這個文件下的URL
    start_urls = ['http://python123.io/ws/demo.html']

    def parse(self, response):              #處理響應,解析內容形成字典,發現新的URL爬取請求
        fname=response.url.split("/")[-1]
        with open(fname,"wb") as f:
            f.write(response.body)
        self.log("保存文件:%s"%name)

   (4),運行爬蟲:scrapy crawl demo

  2,yield:

    

 

     例子:

      

 

     

 

   3,相關類:

    (1)request類:

      

     (2)response類:

      

     (3)Item類:類字典類型,可以按照字典類型操作;表示從HTML中提取的內容

  4,CSS Selector:

    

    

  5,高級使用:

    

 (三)實例:

  實例一:

  1,功能:

    

   2,實現難點:

   3,准備工作:網站選取原則:

    

    爬取鏈接:http://quote.eastmoney.com/stock_list.html#sh 東方財富股票綜合排名

         http://gu.qq.com/xxxxxx/gp  騰訊個股股票信息

           先爬取股票綜合排名:獲取股票代碼,放入搜狐股票的鏈接中轉到個股信息

         爬取股票綜合排名網頁發現:股票簡略信息都在<tbody class="tbody_right" id="datalist"></tbody>中;一個行內是一支股票的信息;一行的第一列是代碼,第二列         是股票名稱  

  4,步驟:

    (1),創建工程和爬蟲  : 工程BaiduStock     scrapy  startproject   BaiduStock            爬蟲stocks           scrapy   genspider  stocks  www.xxx.com

    (2),編寫stocs.py文件:先從東方財富網獲取所有股票代碼 ,然后根據每個股票代碼找到騰訊股票的個股信息,將個股信息封裝到infoDict字典中,最后將爬取數據傳入PIPELINES

    (3),編寫PIPELINES,配置pipelines.py文件:定義對爬取項的處理類;配置ITEM_PIPELINES選項

     (4),運行爬蟲:scrapy  crawl  stocks

#stocks.py文件
# -*- coding: utf-8 -*-
import scrapy
import re
import requests
from bs4 import BeautifulSoup
import bs4

class StocksSpider(scrapy.Spider):
    name = 'stocks'
    start_urls = ['http://quote.eastmoney.com/stock_list.html#sh']

    def parse(self, response):
        html=response.body
        soup=BeautifulSoup(html,"html.parser")
        hrefs=soup.find_all(name="a")
        for href in hrefs:        #從東方財富網爬取所有的股票排行
            try:
                href=href.attrs["href"]
                stock=re.findall(r"[s][hz]\d{6}",href)[0]       #獲取代碼
                url="http://gu.qq.com/"+stock+"/gp"
                yield scrapy.Request(url,callback=self.parse_stock)
            except:
                continue

    def parse_stock(self,response):                 #從騰訊股票個股網頁獲取個股信息封裝到字典infoDict中
        infoDict={}
        for item in response.css('.title_bg'):
            stock_name= item.css('::text').extract()[0]
            stock_code=item.css('::text').extract()[1]
        html=response.body
        print(response.url)
        soup=BeautifulSoup(html,"html.parser")
        div=soup.find(name="div",attrs={"class":"content clear"})
        span=div.find_all(name="span")
        dspan=span[1::2]                        
        ospan=span[::2]                         
        stock_price=ospan[0].string                     #股票價格
        stock_change_point=ospan[1].string              #股票變化點
        infoDict.update({"股票名稱":stock_name,"股票代碼":stock_code,"股票價格":stock_price,"股票變化點":stock_change_point})
        key=[]
        val=[]
        for i in ospan[2:15]:   
            rE=r"[\[a-z]{0,2}\d{0,4}]"
            agei=re.sub(rE,"",i.string)
            agei="".join(agei.split())
            key.append(agei)                            #key中存放股票漢字提示信息
        for j in dspan[1:15]:                           #val中存放股票數據信息
            val.append(j.string)
        key.insert(0,"漲跌幅")
        for i in range(len(key)):
            kv=key[i]
            va=val[i]
            infoDict[kv]=va                             #新增內容
        #print(infoDict)
        yield infoDict                      #將字典內存的數據封裝為Item類轉入PIPELINES
#pipelines.py文件
# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html


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

class BaidustockInfoPipeline(object):
    def open_spider(self,spider):       #爬蟲被調用時pipline啟動的方法
        self.f=open("StockInfo.txt","w")
    def close_spider(self,spider):      #關閉方法
        self.f.close()
    def process_item(self,item,spider): #對每一個pipeline項處理方法
        try:
            line=str(dict(item))+'\n'
            self.f.write(line)          #將數據寫入文件
            
        except:
            pass
        return item
#settings.py文件修改部分
ITEM_PIPELINES = {
    'BaiduStock.pipelines.BaidustockInfoPipeline': 300,
}

      

 

   5,Scrapy提供優化:需要修改,通過改變並發

     

 

 

   

      

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM