scrapy shell
scrapy shell 是scrapy的交互终端,在不启动scrapy(不创建scrapy项目)的情况下调试代码。.
比如要进入百度,在cmd里输入 scrapy shell baidu.com,可以从返回的结果中看到网页已经获取响应,并返回结果。
这时我们可以通过response.进行操作,response.body 获得二进制的源码,response.text 获得字符串形式的源码,response.encoding 获得网页的编码形式,response.url 当前请求的地址,response.xpath(‘路径’),也可以使用xpath获取内容,ctrl+c 终止当前cmd运行的代码。
setting文件补充
在scrapy的setting里进行参数的配置,里面的配置参数很多都是英文字母大写的形式,一般情况下在定义公共的配置都是用大写。要把爬取的数据存储到数据库里,要把爬虫项目连接数据库,要把配置项(如账号密码等)放到setting里面。
在setting里配置,MYSQL_HOST = ‘192.18.0.1’ ,在管道里要进行接收才能放数据库中存放,就需要在pipelines里进行导入 from 根目录.settings import MYSQL_HOST,这时要注意导入的时候根目录是从上往下开始找的,如果之前的文件中重复定义了根目录,要先把之前的根目录进行取消。也可以在爬虫文件中进行导入。
引用settings文件数据的两种方式
爬虫文件和管道文件第一种引入的方式是一样的。
导入之后在爬虫文件中引用settings文件数据的方式有两种,
第一种:
from 根目录.settings import MYSQL_HOST
print(MYSQL_HOST);
第二种:print(self.settings.get(‘MYSQL_HOST’))
在管道pipelines文件里引用settings文件数据的方式有两种,
第一种:
from 根目录.settings import MYSQL_HOST
print(MYSQL_HOST);
第二种:print(spider.settings.get(‘MYSQL_HOST’))
middlewares文件介绍
scrapy框架进行爬取的好处是效率比较高,框架里的文件比较多,每个文件都各司其职,把思路理清楚了之后,用scrapy框架去实现。可以把之前写好的爬虫程序放到scrapy框架里去运行,如果爬取的内容比较多可以用scrapy去实现,每次请求都用随机的请求头(UA),可以在下载中间件设置随机请求头和headers。引擎从爬虫程序中拿到URL之后交给调度器入列,把入好列的url请求给下载器,下载器把生成的response通过下载中间件发送给引擎,爬虫中间件是同样的道理,下载中间件和爬虫中间件用来完成数据之间的传递,下载中间件衔接的是引擎和下载器,爬虫中间件衔接的是引擎和爬虫程序。引擎把请求给下载器的时候并没有发送请求,可以通过下载中间件添加UA和headers,从而使爬虫程序更加安全。
下载中间件是引擎和下载器进行通信的中间件,通过中间件可以设置代理,达到反反爬的目的。middlewares文件里有两个类,一个是SpiderMiddleware爬虫中间件,一个是DownloaderMiddleware下载中间件。
在下载中间件中的类方法中,引擎发送给下载器的内容,会先被下载中间件的process_request函数处理,而下载器返回给引擎的内容会先被下载中间件的process_response函数处理。
start文件
from scrapy import cmdline
# cmdline.execute(['scrapy', 'crawl', 'ua']) # 方法一
cmdline.execute('scrapy crawl ua'.split(" ")) # 方法二
middlewares文件
def process_request(self, request, spider): # 发送请求
# 当每个request通过下载中间件的时候,这个方法都会被调用
# request 就是下载中间件拦截的请求
# spider 就是爬虫类实例化的对象
# Called for each request that goes through the downloader
# middleware.
# Must either:
# - return None: continue processing this request # 默认返回为空,继续发送请求,正常处理request请求
# - or return a Response object # 或者是返回一个response对象,下载中间件直接把返回的response对象给引擎(不正常)
# - or return a Request object # 或者是返回一个request对象,下载中间件把返回的这个新的request对象给下载器处理 # - or raise IgnoreRequest: process_exception() methods of # 或者是返回一个异常
# installed downloader middleware will be called
return None
def process_response(self, request, response, spider):
# 当下载器完成http请求的时候,process_response都会被调用
# Called with the response returned from the downloader.
# Must either;
# - return a Response object # 默认返回response对象
# - return a Request object
# - or raise IgnoreRequest
return response
如果没有加ua,直接进行网站的访问
ua文件
import scrapy
class UaSpider(scrapy.Spider):
name = 'ua'
allowed_domains = ['httpbin.org']
start_urls = ['http://httpbin.org/user-agent']
def parse(self, response):
print(response.text)
运行的结果是:
"user-agent": "Scrapy/2.5.0 (+https://scrapy.org)"
这个时候很容易看到是爬虫程序在访问网页,可以用来去检查ua是否设置成功。在setting里添加请求报头后,打印的就是设置的ua,模拟用户的正常访问,就说明ua设置成功了。如果在发送请求之前,在setting或者爬虫程序process_request里使用进行请求头(随机ua)和代理的设置,可以使爬虫程序更加完善。也可以直接写一个类,重写process_request函数,可以百度随机请求头。
setting文件
DOWNLOADER_MIDDLEWARES = {
# 'mw.middlewares.MwDownloaderMiddleware': 543,
'mw.middlewares.UserAgentDownloaderMiddleware': 543,
}
middlewares文件
# 自定义一个类进行随机请求头的获取
class UserAgentDownloaderMiddleware:
USER_AGENTS = [
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
"Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
"Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
"Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5"
]
# 重写process_request方法
def process_request(self, request, spider):
# 导入random函数,随机获取ua
user_agent = random.choice(self.USER_AGENTS)
request.headers['User-Agent'] = user_agent
运行start文件,可以得到列表内随机的ua。
我们可以让程序多次发起请求,在ua爬虫文件中发起多次请求。
ua文件
import scrapy
class UaSpider(scrapy.Spider):
name = 'ua'
allowed_domains = ['httpbin.org']
start_urls = ['http://httpbin.org/user-agent']
def parse(self, response):
print(response.text)
yield scrapy.Request(
# 访问的网站,只有一个网站,去列表的第一个
# 由于回调函数还是当前函数,可以不需要,这时会打印两个请求头
self.start_urls[0],
# 实现循环打印,dont_filter默认的值是False是去重的,改为True不去重
dont_filter=True
)
这个时候会打印两个请求头,request里的dont_filter的值默认是是False,去重,可以更改位True不去重,实现重复爬取打印。scrapy爬取的速度比较快,可以在setting文件里,打开DOWNLOAD_DELAY,把值改为1,暂停1秒来把时间控制一下。
总结:
第一步,在middlewares文件里面放进随机的请求头列表,
第二步,重写process_request()方法,在这个函数里实现的流程是随机拿到一个ua,通过request.headers[‘User-Agent’]进行ua的设置,
第三步,在setting里开启下载中间件,在scrapy.Request中设置dont_filter=True实现重复爬取,用来设置是否进行去重处理。
在middlewares文件里也可以导入UserAgent库,进行随机请求头的设置
from fake_useragent import UserAgent
class UserAgentDownloaderMiddleware:
USER_AGENTS = [
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
"Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
"Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
"Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5"
]
# 重写process_request方法
def process_request(self, request, spider):
# 第一种方法
# 导入random函数,随机获取ua
# user_agent = random.choice(self.USER_AGENTS)
# request.headers['User-Agent'] = user_agent
# 第二种方法
ua = UserAgent()
user_agent = ua.random
request.headers['User-Agent'] = user_agent