(一)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提供優化:需要修改,通過改變並發