k、scrapy之综合应用

scrapy之综合应用

1、LinkExtractors

LinkExtractors:链接提取器,只负责提取链接,即a标签的内容

1.1、导入

from scrapy.linkextractors import LinkExtractor

1.2、scrapy shell 使用

例:scrapy shell https://www.dytt8.net/html/gndy/dyzz/index.html

#获取连接的路径和文本名称
links = extractor.extract_links(response)
for link in links:
	print(link.url, link.text)

1.3、创建爬虫文件

需要使用crawlspider,CrawlSpider是一个类,它的父类就是scrapy.Spider,所以CrawlSpider不仅有Spider的功能,还有自己独有的功能。CrawlSpider可以定义规则,再解析html内容的时候,可以根据链接规则提取出指定的链接,然后再向这些链接发送请求,所以,如果有需要跟进链接的需求,就可以使用CrawlSpider来实现

scrapy genspider -t crawl 爬虫名  域名
使用模板 crawlspider  创建爬虫类

1.4、读书网

# -*- coding: utf-8 -*-
import scrapy

# 链接提取器
from scrapy.linkextractors import LinkExtractor
# CrawSpider导入
from scrapy.spiders import CrawlSpider, Rule

class ReadSpider(CrawlSpider):
    name = 'read'
    allowed_domains = ['www.dushu.com']
    start_urls = ['https://www.dushu.com/book/1081.html']
    # 建议不要重写父类的pares方法,框架负责实现
    # # 父类的逻辑
    # def parse(self, response):
    #     pass
    # 指定了页面内链接的提取规则,会被父类自动调用
    # callback必须使用字符串传递函数名称
    # follow是否跟进链接(继续提取链接中的链接)
    # LinkExtractor对象的提取规则需要我们制定
    rules = (Rule(LinkExtractor(allow=r'/book/1081_\d+?.html'), callback='parse_item', follow=False),)
    # 可以自定义,只要保证callback的参数与这个函数名一致即可
    # parese_item方法会把所有提取到的请求对象的返回值接收到
    # 如果提取到的链接有重复的,会自动过滤
    def parse_item(self, response):
        book_list = response.xpath('//div[@class="bookslist"]/ul/li')
        for book in book_list:
            item = {}
            #标题
            item['title'] = book.xpath('./div[@class="bookinfo"]/h3/a/@title').extract_first()
            #作者
            item['author'] = book.xpath('./div[@class="book-info"]/p/a/text()').extract_first()
            #图片
            item['img_url'] = book.xpath('./div[@class="book-info"]/div/a/img/@data-original').extract_first()
        
        yield item

2、日志LOG

3、处理POST请求

  • Request

    • url

    • callback

    • meta:元数据,指定一个字典做为参数,用于spider和引擎之间传参

    • headers

    • cookies

    • priority

    • dont_filter

  • Response

    • text:文本数据

    • encoding:文本的编码

    • body:字节码数据

    • meta:元数据

    • status

    • url

    • headers

    • request

  • start_requests(self)

    #定制此方法,这个方法是一个重写方法,不要修改名字和参数
    # -*- coding: utf-8 -*-
    import scrapy
    import json
    
    class FanyiSpider(scrapy.Spider):
        name = 'fanyi'
        allowed_domains = ['fanyi.baidu.com']
        # 重写方法,不是自定义方法,由引擎自动调用
    
        def start_requests(self):
           	post_url = 'http://fanyi.baidu.com/sug'
        	    data = {
        		     'kw': 'baby'
            	}
        	 	# 提交post请求
        		# url  post地址
        		# formdata  post参数
        		# headers   post请求头
        		# callback  回调函数,引擎会把response对象回传给这个指定的函数
        		yield scrapy.FormRequest(url=post_url,formdata=data,callback=self.parse_info)
        		# 自定义的函数,由callback指定的回调方法
        		def parse_info(self, response):
        			obj = json.loads(response.text,encoding='utf-8')
        			string = json.dumps(obj,ensure_ascii=False)
        			# 解析内容即可
        			print(string)
    
    • 删除spider文件中的start_Urls属性和parse函数

    • yield scrapy.FormReuqest():需要在start_request函数内使用此方法返回一个POST请求对象

      • url:POST请求的地址

      • formdata:POST要携带的表单数据

        data = {
        key:value
        }
        
      • headers:定制请求头信息

      • cookies

      • callback:处理解析逻辑的回调函数,需自己定义

    • yield scrapy.Reqeust():提交GET 请求使用的方法

    • yield:方法调用前一般加yield表示返回这个对象给引擎

4、设置代理

  • settings文件设置

    • 开启DOWNLOADER_MIDDLEWARES
  • middlewares文件修改

    • 实现下载中间件指定的类中的process_request方法
    • 添加代码:request.meta['proxy'] = 'http://101.236.60.8:8866'

5、处理登陆

  • cookies设置

    • 需要使用cookie可以设置COOKIES_ENABLED为True
    • 执行步骤同POST请求

6、写入MySql

  • settings中添加新的管道

    ITEM_PIPELINES = {
       'dushuproject.pipelines.DushuprojectPipeline': 300,
       'dushuproject.pipelines.MysqlPipeline': 299,
    }
    
  • settings中添加数据库配置信息

    DB_HOST = '127.0.0.1'
    DB_PORT = 3306
    DB_USER = 'root'
    DB_PWD = '123456'
    DB_NAME = 'test'
    DB_CHARSET = 'utf8'
    
  • pipelines文件修改

    from scrapy.utils.project import get_project_settings
    import pymysql
    
    # 添加如下新的管道,用于数据库文件操作
    class MysqlPipeline(object):
        """docstring for MysqlPipeline"""
        def __init__(self):
            settings = get_project_settings()
            self.host = settings['DB_HOST']
            self.port = settings['DB_PORT']
            self.user = settings['DB_USER']
            self.pwd = settings['DB_PWD']
            self.name = settings['DB_NAME']
            self.charset = settings['DB_CHARSET']
            self.connect()
    
        def connect(self):
            self.conn = pymysql.connect(host=self.host,port=self.port,user=self.user,
            password=self.pwd,db=self.name,charset=self.charset)
            self.cursor = self.conn.cursor()
            
        def close_spider(self, spider):
            self.conn.close()
            self.cursor.close()
            
        def process_item(self, item, spider):
            sql = 'insert into book(image_url, book_name, author, info) values("%s", "%s", "%s", "%s")' % (item['image_url'], item['book_name'], item['author'], item['info'])
            # 执行sql语句
            self.cursor.execute(sql)
            return item
    
  • 数据库引擎

    • MyISAM
    • pymysql
posted @ 2021-03-31 07:27  昵称已经被使用  阅读(126)  评论(0)    收藏  举报