以抓取斗鱼的图片为例
一、设置settings.py文件
ITEM_PIPELINES = {
'douyu.pipelines.DouyuImagePipeline': 1,
}
IMAGES_STORE = './桌面/斗鱼' # 存储图片的位置
IMAGES_MIN_HEIGHT = 200 # 所抓取的图片的最小尺寸
IMAGES_MIN_WIDTH = 200
二、添加items.py
class DouyuItem(scrapy.Item):
# define the fields for your item here like:
names = scrapy.Field()
image_urls = scrapy.Field()
images = scrapy.Field()
image_paths = scrapy.Field()
三、编写pipelines.py
在这一部分重写了imagespipeline类中的file_path方法,用来修改图片的名称;其实也可以在这一部分用os.rename来修改图片的名称
def get_media_requests(self, item, info):
for image_url in item['image_urls']:
self.default_headers['referer'] = image_url
yield scrapy.Request(image_url, headers=self.default_headers,
meta={'item': item, 'index': item['image_urls'].index(image_url)})
# 添加meta是为了下面重命名文件名使用
def file_path(self, request, response=None, info=None):
item = request.meta['item'] # 通过上面的meta传递过来item
index = request.meta['index'] # 通过上面的index传递过来列表中当前下载图片的下标
# 图片文件名,item['names'][index]得到名称,request.url.split('/')[-1].split('.')[-1]得到图片后缀jpg,png
image_guid = item['names'][index]+'.'+request.url.split('/')[-1].split('.')[-1]
# 图片下载目录
filename = u'full/{0}'.format(image_guid)
return filename
def item_completed(self, results, item, info):
image_paths = [x['path'] for ok, x in results if ok]
if not image_paths:
raise DropItem("Item contains no images")
item['image_paths'] = image_paths
return item
四、Spider文件的编写
用while循环来实现动态页面(点击下一页网址不变)点击之后爬取页面内容
因为斗鱼的图片加载必须是滚动加载,所以不能直接滚动到最下面
def __init__(self):
self.browser =webdriver.Firefox()
def parse(self, response):
self.browser.get(response.url)
# 因为是动态页面url不变,所以用yeild scrapy.Request不好使
# 所以这里使用while循环点击下一页,终止条件就是没有下一页
while True:
# 使用WebDriverWait()等待数据加载:即确保对应内容加载完成后,再进行相应爬取任务。
# 浏览器滚动条
# self.browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# 实现平滑滚动?????
i = 0
while i < 15:
code = "window.scrollTo(" + str(i * 1000) + "," + str((i + 1) * 1000) + ")"
self.browser.execute_script(code)
# sleep值需要修改
time.sleep(0.8) # 不然会load不完整
i += 1
list_imgs = self.browser.find_element_by_xpath('//ul[@class="clearfix play-list x4"]') \
.find_elements_by_tag_name('li')
if list_imgs:
item = DouyuItem()
imgs = []
names = []
img_paths = []
for li in list_imgs:
img = li.find_element_by_xpath('.//img[@class="JS_listthumb"]').get_attribute('src')
imgs.append(img)
name = li.find_element_by_xpath('.//span[@class="dy-name ellipsis fl"]').text
names.append(name)
item['image_urls'] = imgs
item['names'] = names
item['image_paths'] = img_paths
yield item
try:
# 实现自动爬取下一页
next = self.browser.find_element_by_xpath('//a[@class="shark-pager-next"]').click()
except:
break