欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Scrapy框架基础(二)

程序员文章站 2022-05-07 17:23:52
...

5.scrapy数据建模与请求

5.1 数据建模,通常是在items.py文件中进行数据建模
  • 为什么要数据建模?
    • 1.定义item即提前规划好哪些字段需要抓,防止手误,因为定义好之后,在运行过程中,系统会自动检查
    • 2.配合注释一起可以清晰的知道要抓取哪些字段,没有定义的字段不能抓取,在目标字段少的时候可以使用字段代替。
    • 3.使用scrapy的一些特定组件需要item做支持,如scrapy的ImagesPipeline管道类
5.2 如何建模
  • 在items.py文件中定义提取的字段

    class MyspiderItem(scrapy.Item):
    	name = scrapy.Field() # 讲师的名字
        title = scrapy.Field() # 讲师的职称
        desc = scrapy.Filed() # 讲师的介绍   
    
5.3如何使用模板类

模板类定义以后需要在爬虫中导入并且实例化,之后的使用方法和使用的字典相同

from items import MyspiderItem



class SpiderSpider(scrapy.Spider):
    name = 'spider'
    # 2.检查允许的域名
    allowed_domains = ['itcast.cn']
    # 1.修改启始的urlrl
    start_urls = ['url']

    def parse(self, response):


        # 获取所有教师节点
        node_list = response.xpath('/html/body/div[1]/div[5]/div/div[2]/div/ul/li')
        # print(len(node_list))
        # 遍历节点列表
        for node in node_list:
            # temp = {}
            item = MyspiderItem()
            
            # xpath方法返回的是选择器对象列表,extract()用于从选择器对象中提取数据;如果只有一个值可以使用extract_first()
            item['name'] = node.xpath('./div/h3/text()')[0].extract()
            item['title'] = node.xpath('./div/h4/text()')[0].extract()
            item['desc'] = node.xpath('./div/p/text()')[0].extract()


            yield item
5.4 翻页请求的思路

回顾requests模块是如何实现翻页请求的:

  • 1.找到下一页的URL地址
  • 2.调用requests.get(url)

scrapy实现翻页的思路:

  • 1.找到下一页的URL地址
  • 2.构造url地址的请求对象,传递给引擎
5.5 构造Request对象,并发送请求

实现方法

  • 1.确定url地址
  • 2.构造请求,scrapy.Request(url,callback)
    • callback:指定解析函数名称,表示该请求返回的响应使用哪一个函数进行解析
  • 3.把请求交给引擎:yield scrapy.Request(url,callback)
create_time  创建时间
update_time  更新时间
id            
title        标题
source       来源作者
digest       摘要
content      内容
click        浏览量
index_image_url 图片
category_id     分类id
user_id      用户id
status       发布状态 0是发布
reason       审核不通过的原因
5.6 scrapy.Request的更多参数
scrapy.Request(url[,callback,method='GET',headers,body,cookies,meta,dont_filter=False])

参数:

1.中括号中的参数为可选参数

2.callback:表示当前的url的响应交给哪个函数去处理

3.meta:实现数据在不同的解析函数中传递,meta默认带有部分数据,比如下载延迟,请求深度等。常用在一条数据分布在不同结构的多个页面的情况下。

4.dont_filter:默认为False,会过滤请求的url地址,即请求过的url地址不会被继续请求,对需要重复请求的url地址可以把它设置为True,比如贴吧的翻页请求,页面的数据总是在变化;start_urls中的地址会被反复启动,否则程序吧会启动

5.method:指定POST或GET请求

6.headers:接收一个字典,其中不包括cookies

7.cookies:接收一个字典,专门放置cookies

8.body:接收json字符串,为POST的数据,发送payload_post请求时使用

5.7 meta参数的使用

meta的作用:meta可以实现数据在不同的解析函数中传递

在爬虫文件的parse方法中,提取详情页增加之前callback指定的parse_detail函数:

def parse(self,response)

注意:

  • meta参数是一个字典
  • meta字典中有一个固定的键proxy,表示代理ip

6.scrapy模拟登陆

6.1 scrapy携带cookies直接获取需要登陆后的页面

应用场景

  • 1.cookies过期时间很长,常用于一些不规范的网站
  • 2.能在cookie过去之前把所有的数据拿到
  • 3.配合其他程序使用,比如其使用selenium把登陆之后的cookie获取到保存到本地,scrapy发送请求之前先读取本地cookie
6.2 实现:重构scrapy的starte_requests方法

scrapy中start_url是通过start_requests来进行处理的,其实现代码如下:

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


class Git1Spider(scrapy.Spider):
    name = 'git1'
    allowed_domains = ['github.com']
    start_urls = ['https://github.com/exile-morganna']


    def start_requests(self):
        url = self.start_urls[0]
        temp = '_octo=GH1.1.1665811615.1584509726; _device_id=c462397b76932627bdccfdc3c4ea4947; has_recent_activity=1; _ga=GA1.2.952245887.1584509769; _gat=1; tz=Asia%2FShanghai; user_session=IECJaL_KnLnVA4cAejtZZ1WvYIzGd0jcvrE_N7xlZX9fFa6I; __Host-user_session_same_site=IECJaL_KnLnVA4cAejtZZ1WvYIzGd0jcvrE_N7xlZX9fFa6I; logged_in=yes; dotcom_user=Wang-TaoTao; _gh_sess=Z%2BQ5enKqPJYFwKCmnzlOYZR0LP0slwnSj3sX25Y0oCRlf6NjrbV58qqgkxHjHXIQc4jQQdisVZVgzYD2v1QJH9ftzNfoCDvC0%2BjpVHq3xC%2Fi9Bh3WoHMeFWMGra%2FqoZb%2FsydtcWz%2F5fbwUZcm9aB%2F0tpHAg0ZgvjN40JNZMOs7egeIXIIC5AieiMghJ5vwSwjGURNAXJautIzgLDboHhqJ6eY3pmlBIW5KFj6XJea8DKpi33cQRMjBAhx8NkD31%2FNO2MUW43IbS5ZezQxw%2BW8tsaXwuwM46XGrsvKzFJYYMv36WEz6xJ%2B8lExVQGgJxkzNGj%2BEJy0hCbvGx72Z6O7WfBnPzCDYfX98yXJB%2BX9Xos3ALsB%2Bfsw%2FPIOKetkJJvRNjF7vgzCnvnmqBQYZATvji211GHptqBL3eVNkFIh8KMjqS6iwad%2BOMp9PPs3p7CrMW%2B0430GA2MTtyVtB%2F2mfhPMmPHWGwyGAoXFMY1jK%2BIg2bOdJxzeznPjEPmVlgH9Lr07scwz2ooos1CYnBYfZBGOlgTyzZmHeHa9n4TT6adksUD2DuehxYJWGganXnZsUPffjyiZaSGXG2Bfz%2Bej4h%2FDacqYj9Agk88%2FXIpRQzwYqD%2FHA%2FdqwKrLhaNtdMrAJyEb5y4SZpfcKrSyQPuLWSycOxLWxhzQmgRBngy4iY0ObCv3GpK%2FHUJOuKmfrOfEdwB%2F3AxZ%2BssUphsoWJvOi40S4mD24r4jHc6PF0U760L2TAXKOnkJc%2F0cEmFHZXMosJrXEJ3rZ6RqBIDxGGAfq4HpfZWGDlj76QrTQo6vnjrw2wc4iasYp26h%2F1GMqVK32yPM5iDmPIJA5Q1uEwulvpczN0NG3COqMnlnT1Tjom%2BIOSmYRnPTt9zHEZwr5LNszqb0sQ6AsI7TypDER6AhThJKDQzqwPsHj8vHHIjVH6YMBrkC9ETlBGbaxrmF46fpFdS1kwKiHGo1PDieZ5KAypbvbvHq21q7PlnCFOqAqDGAC8vjYLL58%2FdBgcOHeMWOuALOm2fHrKBVkWegIRuXib7cyrSrDUShlPbYO0ZvYRmfGHuyscn2F2%2Bzg%2FOcIuXZ6Z4KfiwPeeqP3%2FK1b%2BPLa5OYrzXDqA%2FPemLzOiHQppqGjq2%2F%2FP%2FmGl3c60uXTp%2BWY9vbfewuFovnLqb68OO%2BpRdJeujmu2C9a4O1%2BJ4%2BD1ArL59ZWQhaJao%2F1EfYvw6ARim%2F1GPhFGe6L%2Br%2F1KWHEZDjUYnd7ido%2F82GTr4JQxTq1v7HZ9RAUUnWITrl0NH6%2FnrNSFPrbToigPSQZrTOUq5qvDWa5IrItwZ7I7P60PJiHlV9XYeKSAN8BpZipusUjrjpTg0NKbfV0bvvxqUrbAXimvo3K%2Ba6c%2BuMWnlz9Iu3ou1OIVIVZ70WuhBd%2FOUuJsCgRJlUbIhuuAuRBLOGCRCVmtU6ZNfHYuHs9ceqxA1jGhJvjqhDav%2BRUq22mndYQRci%2BJA7PmAML0xw84c6iJ97tKt1SNUFlqkdbGG97jearqrVJec2JFk6XsdpSE%2FPU1bOMYJ32bKmbDpaWugeuQYPiE6O5fApdSByM04BnlebWF2GxQ9eizX2YNSXpbuIB5dpHGpTT8v4kjNJfOMh0AfHF2Xj4bgBNGixyJBjxnk6jCN%2ByE2vAyBknhl06opE9YWS3B7aCcinpP0I%2Fg29hu0ticECzJe9%2FHXlgAfA5rE94%2B36EMNkA3R0d74a02Dxg2Huyza242sGZEDIPWNUOAhr%2Be2VFlejL9xQTjJPDDX9E0%2Fvj79M2eLebcV2A8gXW5jqC2o%2BlSgo8yG%2FxAWd1aSyFvKpXR7yVrTG6B4Qn4SMJeIhzHq%2FiTCbNA5QxeqYuOE%2B3KCYfCxT%2B4nkSg%2BREg4H0MfCfWhSFqhz%2FHXzIFGig2hgNOUiYxk2zVKyFfpJlJ%2B7amXmqYqXoS%2BvGheI9mooxR7zrvGFutnEPKVJS5gqUPb1bFbhrjq1U8jqoU9SID40%2BqGEMhpPI6xMpovnJvLaXIA54x7%2FDN5e8Yg7ko%3D--btXUtFuRy5nay9NQ--TfgJy9iEhmV7Q8au%2FW3Jcw%3D%3D'

        cookies = {data.split('=')[0] : data.split('=')[-1] for data in temp.split('; ')}

        yield scrapy.Request(
            url = url,
            callback = self.parse,
            cookies = cookies,
        )

    def parse(self, response):
        print(response.xpath('/html/head/title/text()').extract_first())

注意:

  • 1.scrapy中的cookie不能够放在headers中,在构造请求的时候有专门的cookies参数,能够接受字典形式的cookie
  • 2.在settings中设置ROBOTS协议、USER_AGENT
6.3 scrapy.Request发送post请求
  • 1.发送post请求
    • 思路分析
      • 1.找到post的url地址:点击登录按钮进行抓包,然后哦定位url地址为https://github.com/session
      • 2.找到请求体的规律:分析post请求的请求体,其中包含的参数均在前一次的响应中
      • 3.是否登录成功:通过请求个人主页,观察是否包含用户名

git2代码:老版本,现在参数已经和以前的不一样,但逻辑大体相同

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


class Git2Spider(scrapy.Spider):
    name = 'git2'
    allowed_domains = ['github.com']
    start_urls = ['https://github.com/login']

    def parse(self, response):
        # 从登录页面响应中解析出post数据
        token = response.xpath('//input[@name="authenticity_token"]/@value').extract_first()

        post_data = {
            'commit':"Sign in",
            'utf8':'√',
            'authenticity_token':token,
            'login':'Wang-TaoTao',
            'password':'wangtaotao',
            'webauthn-support':'supported',
        }



        # 针对登录url发送post请求
        yield  scrapy.FormRequest(
            url = 'https://github.com/session',
            callback=self.after_login,
            formdata=post_data,
        )

    def after_login(self, response):
     yield scrapy.Request('https://github.com/exile-morganna',callback=self.check_login)

    def check_login(self, response):
        print(response.xpath('//input[@name="authenticity_token"]/@value').extract_first())