一、scrapy
scrapy:為爬取網站數據是,提取結構性數據而編寫的應用框架
1. 安裝
??????? pip install scrapy
或者,國內源安裝
??????? pip install scrapy -i https://pypi.douban.com/simple
2. 報錯
??????? 報錯1)building ‘twisted.test.raiser’ extension
原因:缺少twisted庫
解決:下載twisted庫:
??????? a)cp是python版本
??????? b)amd是操作系統版本
????????安裝twisted庫:
??????? 使用:pip install 拖入twisted路徑
twisted庫安裝完成后,再安裝scrapy庫
??????? 報錯2)提示python -m pip install --upgrade pid
?? 解決:運行python -m pip install --upgrade pid
??????? 報錯3)win32錯誤
? 解決:pip install pypiwin32
??????? 仍然報錯)
??????? 解決:安裝Aanacoda工具
二、創建scrapy項目
1)創建scrapy項目
在終端中創建項目:
??????? scrapy startproject 項目名
2)創建爬蟲文件
???????在spiders文件夾中創建爬蟲文件
a)切入spiders目錄下:
????????cd? 項目名\項目名\spiders
?b) 在spiders文件夾中創建爬蟲文件
??????? scrapy genspider 文件名 要爬取的網頁
?一般情況下,要爬取的網頁之前:不需要添加http協議
??????? 否則start-urls中的路徑不成立
? 原因:start_urls的值是根據allowed_domains進行修改的,如果添加了http協議,allowed_domains的值需要用戶手動修改
import scrapyclass Demo001Spider(scrapy.Spider):# 爬蟲的名字:用于運行爬蟲時,使用的值name = "demo001"# 允許訪問的域名allowed_domains = ["www.baidu.com"]# 起始url地址:指的是第一次要訪問的域名# start_urls是在allowed_domains之前添加1個http:// 在allowed_domains之后添加1個/start_urls = ["http://www.baidu.com"]
#執行了 start_urls之后執行的方法 方法中的response就是返回的對象 相當于1)response = urllib.requests.urlopen() 2)response = requests.get()def parse(self, response):pass
?3)運行爬蟲文件
scrapy crawl 爬蟲的名字
?
做了反扒————
?解決:注釋掉君子協議:項目下的setting.py文件中的robots.txt協議
注釋掉:ROBOTSTXT_OBEY = True
?
?三、scrapy項目結構
項目名
??????? 項目名
??????????????? spider文件夾????????(存儲爬蟲文件)
??????????????????????? init????????
??????????????????????? 自定義的爬蟲文件????????(核心功能文件)
??????????????? init
??????????????? items????????(定義數據結構的地方)(爬取的數據包含哪些)
??????????????? middleware????????(中間件)(代理)
??????????????? pipelines????????(管道)(處理下載的數據)
??????????????? settings????????(配置文件)
四、response的屬性和方法
3)4)5)常用
1)response.text
????????獲取響應的字符串
2)response.body
????????獲取響應的二進制數據
3)response.xpath
??????? 直接使用xpath方法解析response中的內容
4)response.extract()
??????? 提取selector對象中的data屬性值
5)response.extract_first()????????
??????? 提取selector對象的第一個數據
五、scrapy工作原理
1). 引擎向spiders要url
2). 引擎將要爬取的url給調度器
3). 調度器將url生成請求對象,放入指定的隊列
4). 從隊列中出隊一個請求
5). 引擎將請求交給下載器進行處理
6).下載器發送請求,向互聯網請求數據
7). 下載器將數據返回給引擎
8). 引擎將數據再次給到spiders
9).spiders通過xpath解析數據
10).? spiders將數據,或者url,給到引擎
11). 引擎判斷該數據,是數據,還是url
??????? a)是數據,交給管道處理
??????? b)還是url,交給調度器處理
六、scrapy shell
??????? scrapy終端
測試xpath和css表達式
免去了每次修改后,運行spiders的麻煩
進入scrapy shell終端:
????????直接在Windows終端輸入:scrapy shell 域名
??????? 使用:
??????????????? 終端中直接執行:
????????????????????????scrapy shell 域名
安裝ipython(高亮,補全)
??????? pip install ipython
七、懶加載中的src
有data-original,src用data-original替代
替換前:src = // ul[ @ id = "component_59"] / li // img / @ src
替換后:src = // ul[ @ id = "component_59"] / li // img / @ data-original
當當網練習中的第一張圖片是none
??????? 原因:沒有data-original
#有data-original,src用data-original替代src = li.xpath('.//img/@data-original').extract_first()# 第一張圖片和其他圖片標簽不一樣,第一張圖片的src是可以使用的 其他圖片的地址是data-originalif src:src = srcelse:#用srcsrc = li.xpath('.//img/@src').extract_first()
當當網:
??????? items.py:
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
from urllib import responseimport scrapyclass DemoDdwItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()# pass#圖片# src = // ul[ @ id = "component_59"] / li // img / @ srcsrc = scrapy.Field()#名字# alt = // ul[ @ id = "component_59"] / li // img / @ altname = scrapy.Field()#價格# price = //ul[@id = "component_59"]/li//p[@class = "price"]/span[1]/text()price = scrapy.Field()
ddw.py
import scrapyclass NddwSpider(scrapy.Spider):name = "nddw"allowed_domains = ["category.dangdang.com"]start_urls = ["https://category.dangdang.com/cp01.07.30.00.00.00.html"]def parse(self, response):# pass# src、name、price都有共同的li標簽# 所有的selector對象,都可以再次調用xpath方法li_list = response.xpath('//ul[@id = "component_59"]/li')for li in li_list:# .extract()提取數據# 有data-original,src用data-original替代src = li.xpath('.//img/@data-original').extract_first()# 第一張圖片和其他圖片標簽不一樣,第一張圖片的src是可以使用的 其他圖片的地址是data-originalif src:src = srcelse:# 用srcsrc = li.xpath('.//img/@src').extract_first()alt = li.xpath('.//img/@alt').extract_first()price = li.xpath('.//p[@class = "price"]/span[1]/text()').extract_first()print(src, name, price)