scrapy提升篇之配置

scrapy提升篇之配置

增加并发

并发是指同时处理的request的数量。其有全局限制和局部(每个网站)的限制。
Scrapy默认的全局并发限制对同时爬取大量网站的情况并不适用,因此您需要增加这个值。 增加多少取决于您的爬虫能占用多少CPU。 一般开始可以设置为 100 。不过最好的方式是做一些测试,获得Scrapy进程占取CPU与并发数的关系。 为了优化性能,您应该选择一个能使CPU占用率在80%-90%的并发数
setting.py文件中写上CONCURRENT_REQUESTS = 100,scrapy中默认的并发数是32

降低log级别

当进行通用爬取时,一般您所注意的仅仅是爬取的速率以及遇到的错误。 Scrapy使用 INFO log级别来报告这些信息。为了减少CPU使用率(及记录log存储的要求), 在生产环境中进行通用爬取时您不应该使用 DEBUG log级别。 不过在开发的时候使用 DEBUG 应该还能接受。
setting.py文件中设置LOG_LEVEL = 'INFO'

禁止cookies

除非您 真的 需要,否则请禁止cookies。在进行通用爬取时cookies并不需要, (搜索引擎则忽略cookies)。禁止cookies能减少CPU使用率及Scrapy爬虫在内存中记录的踪迹,提高性能。
COOKIES_ENABLED = False

禁止重试

对失败的HTTP请求进行重试会减慢爬取的效率,尤其是当站点响应很慢(甚至失败)时, 访问这样的站点会造成超时并重试多次。这是不必要的,同时也占用了爬虫爬取其他站点的能力。
RETRY_ENABLED = False

减少下载超时

如果您对一个非常慢的连接进行爬取(一般对通用爬虫来说并不重要), 减小下载超时能让卡住的连接能被快速的放弃并解放处理其他站点的能力。
DOWNLOAD_TIMEOUT = 15,其中15是设置的下载超时时间

禁止重定向

除非您对跟进重定向感兴趣,否则请考虑关闭重定向。 当进行通用爬取时,一般的做法是保存重定向的地址,并在之后的爬取进行解析。 这保证了每批爬取的request数目在一定的数量, 否则重定向循环可能会导致爬虫在某个站点耗费过多资源。
REDIRECT_ENABLED = False

使用user_agent池

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
from scrapy import log
import random
from scrapy.downloadermiddlewares.useragent import UserAgentMiddleware
class RotateUserAgentMiddleware(UserAgentMiddleware):
# for more user agent strings,you can find it in http://www.useragentstring.com/pages/useragentstring.php
user_agent_list = [
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 "
"(KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
"Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 "
"(KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 "
"(KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 "
"(KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 "
"(KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 "
"(KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
"Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 "
"(KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 "
"(KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 "
"(KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 "
"(KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 "
"(KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 "
"(KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 "
"(KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 "
"(KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 "
"(KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 "
"(KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 "
"(KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 "
"(KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
]
def process_request(self, request, spider):
ua = random.choice(self.user_agent_list)
if ua:
# 显示当前使用的useragent
print "********Current UserAgent:%s************" % ua
# 记录
log.msg('Current UserAgent: ' + ua)
request.headers.setdefault('User-Agent', ua)

爬虫请求常见的错误

1
2
3
4
5
6
7
8
9
10
11
12
13
200:请求成功 处理方式:获得响应的内容,进行处理
201:请求完成,结果是创建了新资源。新创建资源的 URI 可在响应的实体中得到 处理方式:爬虫中不会遇到
202:请求被接受,但处理尚未完成 处理方式:阻塞等待
204:服务器端已经实现了请求,但是没有返回新的信 息。如果客户是用户代理,则无须为此更新自身的文档视图。 处理方式:丢弃
300:该状态码不被 HTTP/1.0 的应用程序直接使用, 只是作为 3XX 类型回应的默认解释。存在多个可用的被请求资源。 处理方式:若程序中能够处理,则进行进一步处理,如果程序中不能处理,则丢弃
301:请求到的资源都会分配一个永久的 URL,这样就可以在将来通过该 URL 来访问此资源 处理方式:重定向到分配的 URL
302:请求到的资源在一个不同的 URL 处临时保存 处理方式:重定向到临时的 URL
304 请求的资源未更新 处理方式:丢弃
400 非法请求 处理方式:丢弃
401 未授权 处理方式:丢弃
403 禁止 处理方式:丢弃
404 没有找到 处理方式:丢弃
5XX 回应代码以“5”开头的状态码表示服务器端发现自己出现错误,不能继续执行请求 处理方式:丢弃

使用ip代理池

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import random  
import scrapy
import logging
class proxMiddleware(object):
#proxy_list=[{'http': 'http://123.157.146.116:8123'}, {'http': 'http://116.55.16.233:8998'}, {'http': 'http://115.85.233.94:80'}, {'http': 'http://180.76.154.5:8888'}, {'http': 'http://139.213.135.81:80'}, {'http': 'http://124.88.67.14:80'}, {'http': 'http://106.46.136.90:808'}, {'http': 'http://106.46.136.226:808'}, {'http': 'http://124.88.67.21:843'}, {'http': 'http://113.245.84.253:8118'}, {'http': 'http://124.88.67.10:80'}, {'http': 'http://171.38.141.12:8123'}, {'http': 'http://124.88.67.52:843'}, {'http': 'http://106.46.136.237:808'}, {'http': 'http://106.46.136.105:808'}, {'http': 'http://106.46.136.190:808'}, {'http': 'http://106.46.136.186:808'}, {'http': 'http://101.81.120.58:8118'}, {'http': 'http://106.46.136.250:808'}, {'http': 'http://106.46.136.8:808'}, {'http': 'http://111.78.188.157:8998'}, {'http': 'http://106.46.136.139:808'}, {'http': 'http://101.53.101.172:9999'}, {'http': 'http://27.159.125.68:8118'}, {'http': 'http://183.32.88.133:808'}, {'http': 'http://171.38.37.193:8123'}]
proxy_list=[
"http://180.76.154.5:8888",
"http://14.109.107.1:8998",
"http://106.46.136.159:808",
"http://175.155.24.107:808",
"http://124.88.67.10:80",
"http://124.88.67.14:80",
"http://58.23.122.79:8118",
"http://123.157.146.116:8123",
"http://124.88.67.21:843",
"http://106.46.136.226:808",
"http://101.81.120.58:8118",
"http://180.175.145.148:808"]
def process_request(self,request,spider):
# if not request.meta['proxies']:
ip = random.choice(self.proxy_list)
print ip
#print 'ip=' %ip
request.meta['proxy'] = ip

设置延迟

DOWMLOAD_DELY=3,设置延迟下载可以避免被发现

启用调试工具 命令行调试

scrapy shell url 查看网页,不过这种方式可能对于要请求头的网页不行,对于一般的网页还是可以的
scrapy view shell 用来查看动态加载的网页,如果查看的网页用了动态加载,那么用这个命令行打开的网页就是不完整的,肯定缺少了什么

编辑器中的调试

1
2
3
from scrapy.shell import inspect_response
def paser(self,response):
inspect_response(response,self) #当程序运行到这里就会跳出终端,并且在终端出现调试命令,当然这个可以随便写

暂停和恢复爬虫

初学者最头疼的事情就是没有处理好异常,当爬虫爬到一半的时候突然因为错误而中断了,但是这时又不能从中断的地方开始继续爬,顿时感觉心里日了狗,但是这里有一个方法可以暂时的存储你爬的状态,当爬虫中断的时候继续打开后依然可以从中断的地方爬,不过虽说持久化可以有效的处理,但是要注意的是当使用cookie临时的模拟登录状态的时候要注意cookie的有效期
只需要在setting.py中JOB_DIR=file_name其中填的是你的文件目录,注意这里的目录不允许共享,只能存储单独的一个spdire的运行状态,如果你不想在从中断的地方开始运行,只需要将这个文件夹删除即可
当然还有其他的放法:scrapy crawl somespider -s JOBDIR=crawls/somespider-1,这个是在终端启动爬虫的时候调用的,可以通过ctr+c中断,恢复还是输入上面的命令

不按照robots.txt

ROBOTSTXT_OBEY = False

配置请求头

ROBOTSTXT_OBEY = False

1
2
3
4
5
DEFAULT_REQUEST_HEADERS={{
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'User-Agent':'......' #在此处设置
}}