3.开发流程
1、创建一个项目
2、将scrapy项目放到pycharm,目录结构如下:
如果不按上面的方式,运行命令会发生找不到命令的情况。
3、创建一个spider
4、在settings.py中,修改robots协议
5.在新建好的spider中,初始化start_urls列表,告诉scrapy要下载的网页有哪些?
6、添加请求,请求头需要在settings.py配置文件中设置。
7、在spider文件中的parse方法里测试是否能够获取到页面数据。
Scrapy的启动方法:scrapy crawl maoyan_spider
8.在items.py中,定义我们要爬取的字段是那些。
9、在parse方法中实例化一个item
10、从页面提取数据。
补充:
Response.xpath返回的就是一个selector对象,selector 对象可以继续调用xpath方法提取元素。
可以通过以下两个方法,从selector对象中获取字符串内容。
extract_first()--相当于text[0]
extract()---取出返回的整个list中的每一个的字符串内容。
scrapy crawl maoyan_spider --nolog 可以不打印日志运行scrapy
12.scrapy如何发送二次请求
在scrapy项目中,如果我们想要在parse方法中继续发送一个请求,请求其他url,我们可以通过yield一个scrapy.Request()对象,这样,scrapy引擎就会将他加入调度队列进行下载,将下载好的结果传给该对象的callback参数所对应的回调方法。
#想要在parse方法里面二次请求
yield scrapy.Request(
url = new_url,#request对象所对应的url
callback=self.parse_area,#callback就是这个request对象被scrapy自动下载好后,得到response交给谁处理。
encoding='utf-8'#编码格式
)
该对象还有一个meta参数,用来传递参数。
yield scrapy.Request(url,callback=self.parse_detail,meta={'data':item})
(1)将提取完全的item,yield出去,(yield item),此时scapy就会将将这个item传给pipelines.py中类的process_item(self, item, spider):来处理。
(2)要想使用pipelines.py中的类来存储item,必须将该类配置到settings.py中。
补充:
增量爬虫:让我们爬虫程序每次运行后,都能保证让数据库中数据稳定增长,不会出现重复。
1.在数据存储的时候,用update,将其中的一个参数upsert设置为true,这样就表示数据库中有数据,就更新,没有,就插入,可以避免重复插入。
14.如何实现自定义下载(在下载中间件):比如现在想用selenium+phantomjs
比如豆瓣读书案例,只能通过selenium+phantomjs来获取数据。
自定下载的步骤:
(1)创建一个MyMiddlerWare.py文件。
(2)在这个文件中创建一个类。
这个类就是我们的下载中间件。当一个request要被下载器下载之前,这个中间件可以帮我们捕捉到他,可以提前对这个request做一些操作,比如你自己下载后之后,下载器就不会自己下载了。捕捉的方法是: def process_request(self, request, spider):
(3)想要让这个下载中间件生效,必须在settings.py中配置如下内容。
15、scrapy第二种发初始请求的方法。
使用 spider中的def start_reuqst():
这种方法优点主要是:可以手动的设置初始url的一些request信息,比如可以自带meta参数,比如可以给他收到设置一些请求头。
16.scrapy中如何使用cookie?
Scrapy默认会自己定义cookie信息,你设置到default_requests_headers这个配置信息中的cookie是不会生效的,如果想让他生效,必须将下面这个配置打开。
17.linkextract类,可以帮我们快速找出页面中链接。
from scrapy.linkextractors import LinkExtractor
#创建一个le对象,对象接受参数就是你想筛选的链接的xpath,他会将你所写xpath的页面元素中的所有的链接都筛选出来,这个参数是一个list,可以接受多个xpath
le = LinkExtractor(restrict_xpaths=['//div[@class="l"]/ul/li/span[1]'])
#得到这links就是所有的link对象所对应的列表。
循环这个列表用link.url就可以获取url
links = le.extract_links(response)
18.日志记录
在配置文件中做如下配置:
LOG_FILE:日志文件的名称
LOG_ENABLE:True,开启日志
LOG_LEVEL: (写DEBUG则DEBUG、INFO、WARNING、ERROR、CRITICAL的信息都会写在日志里,写INFO则INFO、WARNING、ERROR、CRITICAL的信息都会写在日志里)
Scrapy提供5层logging级别:
CRITICAL - 严重错误(critical)
ERROR - 一般错误(regular errors)
WARNING - 警告信息(warning messages)
INFO - 一般信息(informational messages)
DEBUG - 调试信息(debugging messages)
LOG_ENCODING:‘utf-8’
补充
1.scrapy中先测试request.text是否有值
2.如果没有值,再把cookie设置在setting.py中(注意:需要将COOKIE_ENABLE = FALSE 打开,因为scrapy默认会使用自己已经封装好的cookie值,因此我们需要将其关掉,使用自己设置的cookie,将其放到setting.py 中的heard中)
3.如果还获取不到就在(下载中间件中写selenium和phantomjs自己写获取页面response不用scrapy中下载器中封装好的方法)
4.response.urljoin(url) 可以将相对路径直接变为绝对路径,这样我们不用去手动的字符串拼接了。
5.生成器:
def func():
list[1,2,3,4,5,6]
for i in list:
yield i
for i in func()
print i #输出的结果就是生成器func yield 出来的i值
因为生成器是迭代的 所以遍历出来的i值就是生成器yield出来的值
1. scrapy是一个爬虫框架,但是他不支持分布式。
2 .scrapy-redis,通过scrapy上增加一个redis组件,这个redis里面设置了带爬取url的列表和每个url的指纹集合,通过这两,做到了分布式,使得多台电脑可以联合爬取一个任务。
scrapy分布式—以笔趣阁项目做分布式(是目录scrapy项目中的biquge_redis,biquge是正常的scrapy项目)
1.什么是分布式?
将一个任务分割成多份,每一份由一个计算机完成,最后所有的计算机能够成为一个整体,得到这个任务的结果。
分布式数据库:
产生的原因:
原来一个数据库都是放在一台电脑上的,但是由于用户量的增多,造成数据库压力很大,所以产生一个思想,就是用多台电脑可以提供同样的数据库服务。
2.scrapy分布式:原来的项目是部署在一台电脑上的,这样爬取速度虽然很快,但是我们还能提升,联想到分布式的思想,我们是否可以通过多台电脑进行配合爬取,这样我们的爬取速度就能大幅度提升。
分布式爬虫就是:【多台电脑爬取同一个项目】。
3.scrapy和scrapy-redis的区别:
(1)scrapy是一个爬虫框架,但是他不支持分布式。
(2)scrapy-redis,通过scrapy上增加一个redis组件,这个redis里面设置了带爬取url的列表和每个url的指纹集合,通过这两,做到了分布式,使得多台电脑可以联合爬取一个任务。
4.scrapy分布式部署步骤:
1.导入:from scrapy_redis.spiders import RedisSpider
更改spider继承,让spider继承RedisSpider
2.注释start_urls,新建一个py文件,用来将url存储到redis数据中。---设置任务。
3.在spider增加类变量redis_key,
致辞,spider设置完毕
4.在settings中进行配置。
(1)主机setting配置:
###配置scrapy-redis调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
###配置url去重
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline': 300
}
SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue'
###主机名
REDIS_HOST = 'localhost' #主机写localhost 从机写主机的地址将来将数据存到主机上
##端口号
REDIS_PORT = 6379
(2)从机步骤:
1,将star_urls初始化的代码全部注释。
2.从机的redis可以关闭
3、'REDIS_HOST':主机ip,
'MONGO_URI':'localhost'
从机setting配置:
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 去重
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue'
# ITEM_PIPELINES = {
# 'scrapy_redis.pipelines.RedisPipeline': 300
# }
REDIS_HOST = '10.10.123.173' #主机写localhost 从机写主机的地址将来将数据存到主机上
REDIS_PORT = 6379
MONGO_URL = '10.10.123.173' #主机写localhost 从机写主机的地址将来将数据存到主机上
MONGO_DATABASE = 'biquge'