尚硅谷当当scrapy框架笔记
作者:互联网
#尚硅谷当当网爬取
#dangpy.py
import scrapy
from scrapy_dangdang.items import ScrapyDangdangItem
class DangpySpider(scrapy.Spider):
name = 'dangpy'
#如果多页下载,要调整允许域名
allowed_domains = ['category.dangdang.com']
start_urls = ['http://category.dangdang.com/cp01.54.06.19.00.00.html']
base_url='https://category.dangdang.com/pg'
page=1
def parse(self, response):
#pipelines下载数据
# items定义数据结构
#src=//ul[@id="component_59"]/li/img/@src
# alt=//ul[@id="component_59"]/li/img/@alt
#price=//ul[@id="component_59"]/li/p[@class="price"]/span[1]/text()
#所有selector对象,都可以再次调用xpath方法
li_list=response.xpath('//ul[@id="component_59"]/li')
for li in li_list:
src=li.xpath('.//img/@data-original').extract_first()#图片做了懒加载,即看到图片才会加载,直接data-origanal即可,但当当第一张图片没有data-original,第一张图片路径和其他的不一样
if src:#src存在不为none
src=src
else:
src=li.xpath('.//img/@src').extract_first()
name = li.xpath('.//img/@alt').extract_first()
price=li.xpath('.//p[@class="price"]/span[1]/text()').extract_first()
#print(src,name,price)
book=ScrapyDangdangItem(src=src,name=name,price=price)
# 获取一个book就将book交给piplines
yield book
#每一页的爬取的业务逻辑全都是一样的,所以我们只需要将执行的那个页的请求再次调用parse方法
#https://category.dangdang.com/pg2-cp01.54.06.19.00.00.html
#https://category.dangdang.com/pg3-cp01.54.06.19.00.00.html
if self.page<100:
self.page=self.page+1
url=self.base_url+str(self.page)+'-cp01.54.06.19.00.00.html'
#怎么调用parse方法
# scrapy.Request就是scrapy的get请求
#url就是请求地址,callback是要执行的函数,不需要加()
yield scrapy.Request(url=url,callback=self.parse)
'''yield 1.带有yield的函数不再是一个普通函数,而是一个生成器generator,可用于迭代 2.yield是一个类似return的关键字,迭代一次遇到yield时就返回yield,后面(右边)的值。重点是:下一次迭代 时,从上一次迭代遇到的yield后面的代码(下一行)开始执行 3.简要理解:yild就是return返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后(下一行)开始
'''
#settings.py
BOT_NAME = 'scrapy_dangdang'
SPIDER_MODULES = ['scrapy_dangdang.spiders']
NEWSPIDER_MODULE = 'scrapy_dangdang.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36'
ITEM_PIPELINES = {
#管道可以有很多个 管道有优先级 优先级的范围是1-1000 值越小优先级越高
'scrapy_dangdang.pipelines.ScrapyDangdangPipeline': 300,
'scrapy_dangdang.pipelines.DangDangDownPipline': 301
}
# Obey robots.txt rules
ROBOTSTXT_OBEY = False#机器人协议
LOG_LEVEL='ERROR'#只允许错误日志出现
#items.py
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
import scrapy
class ScrapyDangdangItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
#通俗的说你要下载的数据都有什么
src=scrapy.Field()
name = scrapy.Field()
price = scrapy.Field()
#pipelines.py
# 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
# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
#如果想使用管道的话,那么就必须在settings中开启管道
class ScrapyDangdangPipeline:
#item就是yield后面的book对象
def open_spider(self,spider):#在爬虫文件开始之前就执行的一个方法
self.fp=open('book.json','w',encoding='utf-8')
def process_item(self, item, spider):
#1.write()必须要写一个字符串 而不能是其他的对象
#2.w模式 会每一个对象都打开一次文件 覆盖之前的内容,a追加
# with open('book.json','a',encoding='utf-8')as fp:#这种模式不推荐,因为没传递过来一个对象就打开一次文件,操作过于频繁
# fp.write(str(item))
self.fp.write(str(item))
return item
def close_spider(self,spider):#在爬虫文件执行完后的一个方法
self.fp.close()
import urllib.request
#多条管道开启
#定义管道类
class DangDangDownPipline:
def process_item(self, item, spider):
url='http:'+item.get('src')
name=item.get('name').replace('/','_')#防止名字中出现/符号是路径混乱
filename= './books/'+name+'.jpg'
urllib.request.urlretrieve(url=url,filename=filename)
# 'scrapy_dangdang.pipelines.DangDangDownPipline': 301
return item
''' img=requests.get(url=url).content
img_name = item.get('name')+'.jpg'
imgPath = r'./book2/' + img_name # 图片存储的路径
with open(imgPath, 'wb') as fp:
fp.write(img) # 'scrapy_dangdang.pipelines.DangDangDownPipline': 301
'''
标签:src,name,当当,self,item,scrapy,dangdang,硅谷 来源: https://www.cnblogs.com/wzc6/p/16102140.html