1、创建项目
scrapy startproject bizhi
2、创建爬虫
scrapy genspider bizhispider www.netbian.com
要爬取的壁纸网站 网址域名www.netbian.com
3、编写前的一些准备
启动脚本
新建Python文件run.py
from scrapy import cmdline
cmdline.execute('scrapy crawl bizhispider'.split())
设置日志输出水平
进入settings.py文件
LOG_LEVEL = 'WARNING' # 讲日志的输出水平设置为警告水平。scrapy crawl 输出的日志太多看着难受
不设置的日志输出(下图)太多太乱看着不方便不好找重点,设置后只有警告以上级别的输出才会打印出来(警告、错误等)
关闭robots协议
进入settings.py设置
ROBOTSTXT_OBEY = False # 这个协议在书面上规定了爬虫可爬取的内容范围(只是一种口头约定,没有用技术手段限制),可以到网址的根目录下+/robots.txt查看
设置请求头
进入settings.py设置
USER_AGENT = ' Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36'
编写爬虫spider
思路:首先分析页面,网页下面有页码因此我们要一页页的爬取肯定得有翻页操作。通过连续观察几个页面这个页面的结构是类似的,我们只需要分析好一个页面讲一个页面的图片爬完后进行翻页操作再以同样的方法爬取下一页就可以了。
图1
大概思路有了就开干。首先分析一个页面爬取一个页面中的壁纸。爬取红色框中的壁纸,通过xpath将此部分选择出来,得到各个壁纸对应的二级页面链接(二级页面 点击图2中的任一个壁纸进入这个壁纸的下载页面图3)。
图 2
图3
通过xpath找到图片url进行下载。
(xpath可以看这篇文章)
import scrapy
from scrapy import Request
import requests
class BizhispiderSpider(scrapy.Spider):
name = 'bizhispider' # 爬虫名称
shulian = 0
#allowed_domains = ['netbian.com/'] # 允许爬取的范围,给注释了不然二次请求的时候由于二次请求的网址不在允许的范围不能正确运行。另一种方法,还可以在Rquest请求时加入dont_filter参数表示不对链接去重同时不受规定的范围限制。
start_urls = ['http://www.netbian.com//'] # 爬取的网址
def parse(self, response):
hrefs = response.xpath('//*[@id="main"]/div/ul/li/a/@href').extract() # 爬取出第一幅图的红框部分得到每张壁纸的二级页面的链接(二级页面的url)。
for href in hrefs[:-1]: # 遍历每个二级页面进行壁纸下载(最后一个链接为下一页,链接不要(看图1))
url = response.urljoin(href)
yield Request(url=url, callback=self.delwith) # 将壁纸的url用生成器抛出,用delwith下载图片
next_page = response.xpath("//div[@class='page']/a[@class='prev']/@href").extract() # 获取下一页链接
next_page = response.urljoin(next_page[-1]) # 拼接链接
yield Request(url=next_page) # 进行翻页操作
def delwith(self,response): # 下载图片
src = response.xpath('//*[@id="main"]/div[3]/div/p/a/img/@src').extract_first()
name = response.xpath('//*[@id="main"]/div[3]/div/p/a/img/@title').extract_first()
image = requests.get(src)
with open('/home/lmx/python/paqubianbizhi/bizhi/images/'+name+'.jpg','wb') as file:
file.write(image.content)
print(name+'下载完成') # 每下载一张提示一下