spider数据挖掘-----7、scrapy框架(三)

一、CrawlSpider类(有rule功能可以不用层层解析)
重新创建爬虫文件,不用默认爬虫类模板,用crawlspider类模板
创建好爬虫文件后,输入scrapy genspider -l(进入模板列表)
然后选择换用其他模板,默认是basic,这里要换成
scrapy genspider -t(选择使用的模板) crawl name(随便起的名字) 域名
创建好后,文件里会自动导入rule和LinkExtractor对象

Rule(定义三种规则:1、如何爬取url(LinkExtrac对象) 2、形成请求 3、响应的处理)
Rule用来定义CrawlSpider的爬取规则
ruless=(Rule(LinkExtractor(只能用来提取url)(allow=r’item‘(通过正则表达式来提取url)),callback=’parse_item‘ , follow = true),process_links=None)
start_urls发送请求后,引擎把响应交给了ruless,然后通过LinkExtrac提取到了次级页面url,提取到url后就会形成请求,然后引擎又拿到新的response后,
再把response通过callback参数交给parse_item的定义方法进行解析

allow=r’item‘中item用url填入即可把需要提取的网页都提取出来,需要提取多个,则可以设置一些正则的规则,比如\d(匹配数字)
提取完之后会有很多相同的url,但是CrawlSpider会自动过滤,所以不用担心会重复。

follow = true属于开启状态,表示除了提取到url后,通过callback除了发送响应给parse_item解析,还会返回给ruless,还有内部的url要提取
开启后,会另外返回一次看rule中的LinkExtractor对象允许的url有没有在他得到的新的响应里找得到,如果有就执行那一项
follow之后对所有的rule进行一次访问,而不是一个,符合的都会处理,但是为了选取目标位置,有些不是想去的url可以通过设置筛选进行限制避免造成混乱
在需要被限制的网页的对应url增加restrict_xpath=’//div【@class=~~~】‘,里面填的是在该要求下,返回的对象只能在该标签里找对应的url

process_links=None,用于把LinkExtractor设置好的allow的url放到一个实例方法中进行处理(执行在LinkExtrac对象发起准确请求),
把None改成那个方法的名称就可以使用,用来限制爬取的数量
放到一个实例方法中也要yield ,发出请求,一定要有返回否则会报错

在settings文件中设置访问速度,DOWNLOAD_DELAY = 3设置延迟限制,让爬虫伪装速度像浏览器一样

执行rule的时候rules = (
Rule(LinkExtractor(allow=r’http://book.zongheng.com/book/\d+.html’), callback=‘parse_item’, follow=True,process_links=“book_page”),
其后面必须加一个逗号,否则会报错
)

rule的LinkExtractor像scrapy.request(url,callback)中的url,callback=‘parse_item’,像其中的callback

’‘ . join(~~~)能很好的拼接内容

参数:
link_extractor Link Extractor对象,它定义如何从每个已爬网页面中提取链接。
callback 回调函数
cb_kwargs 是一个包含要传递给回调函数的关键字参数的dict
follow 它指定是否应该从使用此规则提取的每个响应中跟踪链接。
process_links 用于过滤连接的回调函数
process_request 用于过滤请求的回调函数

二、案例实践

构造三个item类,用来分装三个包 ,传入章节中小说内容的item的那个包的模块需要传入一个章节url的item,当作媒介来让item解析的过程中能找到目标

pipe存储数据,数据放入到pipe后,pipe把数据存储到mysql数据库中
用到数据库,在settings中写入配置好一个数据库(写入mysql数据库的创建代码)
1、连接mysql数据库:(用pymysql来进行连接)
加载出来数据库,然后通过条件判断进行字典模式的传参
2、接收数据:
通过select insert into来读写数据进数据库中
通过commit提交
**data_config[“config”]分解data_config中config的字典为多个键值
小说存储判断:如果存在就可以不进行存储了

settings中的数据库写的数据库名和密码等信息,一定要对应上自己设置好的

三、CrawlSpider页面去重
源代码内含有request_to_follow的方法

pymysql:execute(加查询条件参数,能查询符合该条件的一些信息,然后再加一个arge(列表或元组,查询条件要放%s来接受)参数,可以用来对比是否有该参数)
execute加插入条件参数,通过再加一个元组参数来进行匹配插入数据
1 使用execute()逐行插入,不能插入元组列表(【(元组),(元组),(元组)】,中括号套元组)
2 使用executemany()批量插入,用元组列表来传章节信息,速度很快
使用excutemany(sql, list)批量插入时,List中数据类型必须为Tuple元组
在mysql插入数据和在pymysql插入数据的方式有些不同
commit是提交

navicat:是一个管理mysql的工具
1、mysql使用起来不方便
2、界面形式
navicat使mysql图形化,让mysql没有图形的黑色界面,变得丰富
在其中的表对象增加栏位,id设置自动递增,设置好对应信息名称的栏位,用来接收对应的数据,保存时输入表名,数据库就有该表了
navicat用来手动创建数据库文件和信息栏非常方便

return item返回引擎
return DropItem丢弃

self.conn = pymysql.connect(**data_config["config"])
其中
		**data_config["config"]是将字典解析成元组形式,冒号换成等号
		(host=localhost,port:3306,``````)
				
spider.conn = self.conn          在这作为回传,和item使用的回传一样
spider.cursor = self.cursor
sql = "select id from novel where book_name=%s  and author=%s"
self.cursor.execute(sql, (item['book_name'], item['author']))
if not self.cursor.fetchone():
判断是否存在同样的,不存在才执行

execute也像是format那样的一种格式化的类型的方法

execute用元组传,元组内的某一种数据只能扎在一个堆传

executemany用列表传(元组装在里面,多个元组发送,速度快),列表中每一个元组都有相同的种类数据,相当于列表中的某一种数据分开很多部分去传,散开的传,速度极快

sql="update chapter set  content=%s where chapter_url=%s"
content=item["content"]
作为新的请求去找打内容,然后用更新的方式,写进title,ordernum,c_time,chapter_url,catalog_url他们的表单中,表单还要加多一个content来接收,不然重新写一个的话,update不执行

猜你喜欢

转载自blog.csdn.net/qwe863226687/article/details/114117078