scrapy-新浪关注用户内容爬取

第一个需求

从新浪主页抓取当天的所有热门内容。有文字就爬取文字,图片就爬图片,其实直接爬取博文的连接就好。

抓取内容以内容作者为主要的id

爬取作者的昵称和发表日期,博文链接,博文标题。

这里不用登录,因为,热门内容主要是在微博首页,主要的要求就是使用selenium渲染工具去采集动态内容。

第一个问题:

新浪微博的采用下拉式更新的方式,所以需要使用selenium去执行js代码完成下拉的操作。

js='window.scrollTo(0,document.body.scrollHeight);'
browser.execute_script(js)

第二个问题:​

定位相关的元素,获取需要的内容,并完成清洗。

#用户昵称
name=b[0].find_element_by_xpath('//div[@class="list_des"]/div[@class="subinfo_box clearfix"]/a[2]/span').text
ptime=b[0].find_element_by_xpath('//div[@class="list_des"]/div[@class="subinfo_box clearfix"]/span[@class="subinfo S_txt2"]').text
#整合在一起
browser.find_elements_by_xpath('//div[@class="UG_list_v2 clearfix"]/div[@class="list_des"]/div[@class="subinfo_box clearfix"]')
#完整的信息
b=browser.find_elements_by_xpath('//ul[@class="pt_ul clearfix"]/div[@class="UG_list_v2 clearfix"]/div[@class="list_des"]/div[@class="subinfo_box clearfix"]|//ul[@class="pt_ul clearfix"]/div[@class="UG_list_b"]/div[@class="list_des"]/div[@class="subinfo_box clearfix"]|//ul[@class="pt_ul clearfix"]/div[@class="UG_list_a"]/div[@class="subinfo_box clearfix"]')
#清洗出用户和日期
for i in b:
    i.text.split('\n')[0:2]
#获取博文文本内容
b=browser.find_elements_by_xpath('//ul[@class="pt_ul clearfix"]/div[@class="UG_list_v2 clearfix"]/div[@class="list_des"]/h3|//ul[@class="pt_ul clearfix"]/div[@class="UG_list_b"]/div[@class="list_des"]/h3|//ul[@class="pt_ul clearfix"]/div[@class="UG_list_a"]/h3')
#博文链接
content=browser.find_elements_by_xpath('//ul[@class="pt_ul clearfix"]/div[@class="UG_list_v2 clearfix"]/div[@class="list_des"]/h3|//ul[@class="pt_ul clearfix"]/div[@class="UG_list_b"]/div[@class="list_des"]/h3|//ul[@class="pt_ul clearfix"]/div[@class="UG_list_a"]/h3')
content=[i.text.replace('\n','').replace('#','') for i in content]

第三个问题:

等待,因为使用selenium相当于是打开一个浏览器,和正常的浏览器一样。收到网络的影响,加载页面有可能不及时,导致在内容加载前,selenium就判定定位不到相关内容报错。

在这里使用显示等待的方法,并且在每次更新内容时使用time.sleep延迟。下列的方法,会等待10秒,以便于找到ID为下列的元素被加载。

"PCD_pictext_i_v5"
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(browser,10).until(EC.presence_of_element_located((By.ID,"PCD_pictext_i_v5")))

下列是完整的代码,最后保存为json:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
​
from selenium.webdriver.support import expected_conditions as EC
import time
import random
import json
path='F:/NBA_TEAM/slang.json'
option=webdriver.FirefoxOptions()
option.add_argument('-headless')
​
browser=webdriver.Firefox(options=option)
​
browser.get('https://weibo.com/?category=0')
WebDriverWait(browser,10).until(EC.presence_of_element_located((By.ID,"PCD_pictext_i_v5")))
num=10
for i in range(num):# b=browser.find_elements_by_xpath('//ul[@class="pt_ul clearfix"]/div')
#整合在一起
    # browser.find_elements_by_xpath('//div[@class="UG_list_v2 clearfix"]/div[@class="list_des"]/div[@class="subinfo_box clearfix"]')#完整的信息
    user_id_time=browser.find_elements_by_xpath('//ul[@class="pt_ul clearfix"]/div[@class="UG_list_v2 clearfix"]/div[@class="list_des"]/div[@class="subinfo_box clearfix"]|//ul[@class="pt_ul clearfix"]/div[@class="UG_list_b"]/div[@class="list_des"]/div[@class="subinfo_box clearfix"]|//ul[@class="pt_ul clearfix"]/div[@class="UG_list_a"]/div[@class="subinfo_box clearfix"]')
#清洗出用户和日期
    user_id_time=[i.text.split('\n')[0:2] for i in user_id_time]#获取博文文本内容
    content=browser.find_elements_by_xpath('//ul[@class="pt_ul clearfix"]/div[@class="UG_list_v2 clearfix"]/div[@class="list_des"]/h3|//ul[@class="pt_ul clearfix"]/div[@class="UG_list_b"]/div[@class="list_des"]/h3|//ul[@class="pt_ul clearfix"]/div[@class="UG_list_a"]/h3')
    content=[i.text.replace('\n','').replace('#','') for i in content]#博文链接
    content_link=browser.find_elements_by_xpath('//ul[@class="pt_ul clearfix"]/div[@class="UG_list_v2 clearfix"]/div[@class="list_des"]|//ul[@class="pt_ul clearfix"]/div[@class="UG_list_b"]|//ul[@class="pt_ul clearfix"]/div[@class="UG_list_a"]')
    content_link=['https:'+i.get_attribute('href') for i in content_link]
    
   
    js='window.scrollTo(0,document.body.scrollHeight);'
    browser.execute_script(js)
    time.sleep(random.randint(1,3))
    print(i)
​
    
​
data={}
for i in range(len(content_link)):
    data[str(i)]={
        "name":str(user_id_time[i][0]),
        "time":user_id_time[i][1],
        "content":content[i],
        "content_link":content_link[i]
    }
​
​
with open(path,'w',encoding='utf-8') as f:
    json.dump(data,fp=f,ensure_ascii=False)print('all')

不过,这种方式需要等待的时间很长,而且,这种脚本的方式,是必须在抓取完所有数据后才能进行保存,我意识到一个问题,这里每一次遍历都重新创建了一个列表,并丢弃了原来的。因为每次循环,都得重最开始的地方开始抓取。这没什么问题,无非就是去重的问题。问题是保存数据的问题。以后使用scrapy抓取数据的时候肯定是边抓取边保存。​。​我尝试了下拉刷新100次,总的时长是3151秒。差不多52分钟,就算去掉延时的300秒也是47分钟,而总共抓取了800条数据。确实很慢。
在这里插入图片描述

关于去重的问题,使用redis数据库的集合就可以很好的去重,并且保证能够边刷新,边保存,不至于出现意外的时候,数据丢失。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
​
from selenium.webdriver.support import expected_conditions as EC
import time
import random
import json
import redis
r=redis.Redis(host='localhost',port='6379',decode_responses=True)
path='F:/NBA_TEAM/slang.json'
option=webdriver.FirefoxOptions()
option.add_argument('-headless')
​
browser=webdriver.Firefox(options=option)
​
browser.get('https://weibo.com/?category=0')
WebDriverWait(browser,10).until(EC.presence_of_element_located((By.ID,"PCD_pictext_i_v5")))
num=100
​
start=time.time()
for i in range(num):
    print(i)
    
#完整的信息
    user_id_time=browser.find_elements_by_xpath('//ul[@class="pt_ul clearfix"]/div[@class="UG_list_v2 clearfix"]/div[@class="list_des"]/div[@class="subinfo_box clearfix"]|//ul[@class="pt_ul clearfix"]/div[@class="UG_list_b"]/div[@class="list_des"]/div[@class="subinfo_box clearfix"]|//ul[@class="pt_ul clearfix"]/div[@class="UG_list_a"]/div[@class="subinfo_box clearfix"]')
#清洗出用户和日期
    user_id_time=[i.text.split('\n')[0:2] for i in user_id_time]
    for i in user_id_time:
        r.sadd('nameid',i[0])
        r.sadd('time',i[1])
        r.sm
    
#获取博文文本内容
    content=browser.find_elements_by_xpath('//ul[@class="pt_ul clearfix"]/div[@class="UG_list_v2 clearfix"]/div[@class="list_des"]/h3|//ul[@class="pt_ul clearfix"]/div[@class="UG_list_b"]/div[@class="list_des"]/h3|//ul[@class="pt_ul clearfix"]/div[@class="UG_list_a"]/h3')
    content=[i.text.replace('\n','').replace('#','') for i in content]
    for i in content:
        r.sadd('content',i)
#博文链接
    content_link=browser.find_elements_by_xpath('//ul[@class="pt_ul clearfix"]/div[@class="UG_list_v2 clearfix"]/div[@class="list_des"]|//ul[@class="pt_ul clearfix"]/div[@class="UG_list_b"]|//ul[@class="pt_ul clearfix"]/div[@class="UG_list_a"]')
    content_link=['https:'+i.get_attribute('href') for i in content_link]
    for i in content_link:
        r.sadd('contentlink',i)
    
    js='window.scrollTo(0,document.body.scrollHeight);'
    browser.execute_script(js)
    time.sleep(random.randint(1,3))
    
​
    
end=time.time()print('运行时间{}'.format(end-start))
​
​
print('all')
browser.quit()

第二个需求:

完成登录,​从个人新浪微博爬取关注的用户的微博。

抓取内容以内容作者为主要的id

爬取作者的昵称和发表日期,博文内容。

这里主要是使用selenium进行微博登录,截止2020-4-26日,微博网页版登录没有验证,脚本代码如下:

import numpy as np
import cv2
from selenium import webdriver
import time
option=webdriver.FirefoxOptions()
option.add_argument('-headless')
browser=webdriver.Firefox()
browser.get('https://weibo.com/')  
browser.get('https://weibo.com/?category=0')
WebDriverWait(browser,10).until(EC.presence_of_element_located((By.ID,"PCD_pictext_i_v5")))#登录用户
usr=browser.find_element_by_xpath('//input[@id="loginname"]') 
usr.clear()
usr.send_keys('**********') 
pas=browser.find_element_by_xpath('//input[@class="W_input"]')
pas.click()
​
pasw=browser.find_element_by_xpath('//input[@class="W_input W_input_focus"]') 
pasw.clear()
pasw.send_keys('**********') 
browser.find_element_by_xpath('//div[@class="info_list login_btn"]').click()
#跳转到关注人网页
browser.get('https://weibo.com/5748544426/follow?rightmod=1&wvr=6')  
#登录后我的用户名
​
​
 browser.find_element_by_xpath('//div[@class="pf_username"]').text
#获取一页的关注人
fo=browser.find_elements_by_xpath('//div[@class="mod_info"]/div/a[@class="S_txt1"]') 
for i in fo:
    i.text#关注用户名
    i.get_attribute('href')#关注用户主页
​
​
​
#下一页
browser.find_element_by_link_text("下一页").click()#判断还有没有下一页
while(1):
    if browser.find_element_by_link_text("下一页").get_attribute('href') is None:
        print('ok')
        break
    else:
        browser.find_element_by_link_text("下一页").click()
​
​
#进入主页后
browser.get('https://weibo.com/u/5856472352?from=myfollow_all')##用户昵称
browser.find_elements_by_xpath('//h1[@class="username"]')[0].text 
##获取发表时间
​
fo=browser.find_elements_by_xpath('//div[@class="WB_from S_txt2"]')
#获取博文内容
fo=browser.find_elements_by_xpath('//div[@class="WB_text W_f14"]') 

使用text来获取内容,似乎只有16条

会介绍如何使用scrapy对接selenium完成任务​

爬取思路

  • 登录
  • 获取所有的关注人网页链接
  • 访问网页
  • 获取时间、昵称、网页

程序设计思路

我是要使用scrapy对接selenium完成我的关注用户博文的爬取。

  • 问题1:如何对接selenium?通过编写scrapy的下载器中间件,截胡spider的请求并将其改成使用selenium发起request,然后将渲染后的page_source加载到response的body中返回到spider进行解析。。
  • 问题2:如何登录?通过在spider中重写start_request函数,在这个函数中再次调用selenium完成登录并获取cookie。并将cookie定义为一个属性实例,因为selenium是阻塞的,所以完成多个任务会有些麻烦。

在这里我将登陆保存的代码与scrapy分开了,在scrapy中直接获取代码。因为,小项目执行时间短,方便调试代码。

登陆获取cookie代码:
import numpy as np
import cv2
from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
import requests
import time
import json
option=webdriver.FirefoxOptions()
option.add_argument('-headless')
browser=webdriver.Firefox(options=option)
​
browser.get('https://weibo.com/5748544426/follow?rightmod=1&wvr=6')
time.sleep(5)
if WebDriverWait(browser,10).until(EC.presence_of_element_located((By.ID,"loginname"))):
#登录用户
    print('登录')
    time.sleep(10)
    usr=browser.find_element_by_xpath('//input[@id="loginname"]') 
    usr.clear()
    usr.send_keys('*******') 
   
    browser.find_element_by_xpath('//div[@class="info_list login_btn"]').click()
    time.sleep(10)
    js='document.getElementById("myBtn").οnclick=function(){displayDate()}'
    pasw=browser.find_element_by_xpath('//input[@class="W_input W_input_focus"]') 
    pasw.clear()
    pasw.send_keys('******') 
    browser.find_element_by_xpath('//div[@class="info_list login_btn"]').click()
#跳转到关注人网页
    
    time.sleep(10)
    cookie=browser.get_cookies()
    browser.quit()
    print("jieshu")
​
browser=webdriver.Firefox()
path="C:/Users/CAPONEKD/sl/sinlangspider/sinlangspider/spiders/cookies.txt"
with open(path, "w") as fp:
    json.dump(cookie,fp)
​
​
with open(path, "r") as fp:
    cook = json.load(fp)
​
​
browser.get('https://weibo.com/5748544426/follow?rightmod=1&wvr=6')
for cookie in cook:
    browser.add_cookie(cookie)
browser.get('https://weibo.com/5748544426/follow?rightmod=1&wvr=6')
​
time.sleep(6)

如果,之后在调试代码的时候,账号被封了出现404,重新改密码,并重新获取cookie。

scrapy编写

编写item

这是全篇的数据存储,不过本次项目的结果只有三个,所以数据结构比较简单。
主要是关注用户的ID,博文内容,和发表日期。

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
from scrapy import Item, Field


class SinlangspiderItem(Item):
    name_id = Field()#用户ID
    content = Field()#内容
    date = Field()#发表如期


编写spider

完成主要的爬取开始和页面解析,本次项目中,主要是爬取个人的关注用户,和其最近的微博。所以这次涉及到两个方面的问题,一个是爬取个人的关注用户有哪些,另一个是获取各个用户的博文内容。因为是对接selenium所以,会有阻塞,所以是先完成对所有关注用户的爬取,在对关注用户的博文爬取。

import scrapy
from scrapy.http import Request
import time
from sinlangspider import items
class QuotesSpider(scrapy.Spider):
    def __init__(self,**kwargs):
        self.follow_name = set()
        self.follow_url = set()
    name = "slan"
    allowed_domains = ['weibo.com']#允许的域名

    def start_requests(self):
        yield Request('https://weibo.com/5748544426/follow?rightmod=1&wvr=6',
                        callback = self.parse)
        
    def parse(self, response):
        print('---------爬取中-------')
        follow_info = response.xpath(
            '//div[@class="mod_info"]/div/a[@class="S_txt1"]')
        for i in follow_info:
            self.follow_name.add(i.xpath('text()').get())#关注用户名
            self.follow_url.add(i.xpath('@href').get())#关注用户主页
        # print(self.follow_name,self.follow_url)
        try:    
            next_page = response.xpath('//a[@class="page next S_txt1 S_line1"]/@href').get()
            if next_page:
                print('下一页',next_page)
                next_page = next_page.split('#')#下一页利用#分割,#后的不要
                url = 'https://weibo.com'+next_page[0]
                yield Request(url,
                        callback = self.parse)
            else:
                new_url='https://weibo.com'+self.follow_url.pop()
                yield Request(new_url,
                        callback = self.parse2)
        except:
            print('异常没了')
            new_url='https://weibo.com'+self.follow_url.pop()
            yield Request(new_url,
                    callback = self.parse2)
            
    def parse2(self,response):
        name_id = response.xpath('//h1[@class="username"]/text()').get()
        info=response.xpath('//div[@class="WB_detail"]')
        for i in info:
            date = i.xpath('div[@class="WB_from S_txt2"]/a[@class="S_txt2"][1]/text()').get()
            content = i.xpath('div[@class="WB_text W_f14"]/text()').get()
            item = items.SinlangspiderItem(name_id = name_id,
                                content=content,date = date)
            yield item
        print('完成')
        if self.follow_url:

            new_url = 'https://weibo.com'+self.follow_url.pop()
            print('新的开始',new_url)
            yield Request(new_url,
                callback = self.parse2)
        else:
            print('全部结束')
        
    

编写pipeline

pipeline主要是用于对接mongoDB数据库。并保存数据。

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
import pymongo
import json
from scrapy.exceptions import DropItem
class SinlangspiderPipeline(object):
    def __init__(self,mongo_url,mongo_db):
        self.mongo_url = mongo_url
        self.mongo_db = mongo_db

    @classmethod
    def from_crawler(cls,crawler,**kwargs):
        return cls(mongo_url = crawler.settings.get('MONGO_URL'),
            mongo_db = crawler.settings.get('MONGO_DATABASE'))
    
    def open_spider(self,spider):
        self.client = pymongo.MongoClient(self.mongo_url)
        self.db = self.client[self.mongo_db]
        self.mycol = self.db['slan']

    def close_spider(self,spider):
        self.client.close()

    def process_item(self, item, spider):
        print('开始保存')
        if item['name_id']:
            self.mycol.insert_one(dict(item))
            
            return item
        else:
            raise DropItem('信息丢失')

middlewares编写

middlewares主要的作用是用于对接selenium,并且获取给每次请求添加上cookie。并设置随机UA用于反爬。可以的话最好加上代理IP。

class CookieMiddleware(object):
    
    def __init__(self,**kwargs):
        self.option=webdriver.FirefoxOptions()
        self.option.add_argument('-headless')
        self.browser=webdriver.Firefox(options=self.option)

    def __del__(self):
        self.browser.quit()

    def process_request(self, request, spider):
        path="C:/Users/CAPONEKD/sl/sinlangspider/sinlangspider/spiders/cookies.txt"
        with open(path, "r") as fp:
            cook = json.load(fp)
        try:
            self.browser.get(request.url)
            for cookie in cook:
                self.browser.add_cookie(cookie)
            print('新的url',request.url)
            self.browser.get(request.url)
            element = WebDriverWait(self.browser,10).until(
                EC.presence_of_element_located((By.XPATH, '//h1[@class="username"]')))
        
            return HtmlResponse(
                url=request.url, body=self.browser.page_source,
                request=request, encoding='utf-8', status=200)
        except TimeoutException:
            return HtmlResponse(
                    url=request.url, status=500, request=request)

    
class RandomUserAgent(object):
    # Not all methods need to be defined. If a method is not defined,
    # scrapy acts as if the downloader middleware does not modify the
    # passed objects.

    def __init__(self,agents):
        self.agents=agents
    @classmethod
    def from_crawler(cls, crawler):
        # This method is used by Scrapy to create your spiders.
        # s = cls()
        # crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        return cls(crawler.settings.getlist('USER_AGENTS'))

    def process_request(self, request, spider):
      
        request.headers.setdefault('User-Agent',random.choice(self.agents))
        print(request.headers['User-Agent'])

settings设置

#用于添加项目的地址
PROJECT_DIR = os.path.dirname(os.path.abspath(os.path.curdir))
#robots.txt禁用
ROBOTSTXT_OBEY = False
#下载器中间件启用
DOWNLOADER_MIDDLEWARES = {
   #'sinlangspider.middlewares.SinlangspiderDownloaderMiddleware': 543,
    'sinlangspider.middlewares.RandomUserAgent':100,
    'sinlangspider.middlewares.CookieMiddleware':543
}
#mongodburl
MONGO_URL = 'mongodb://localhost:27017/'
#mongo数据库
MONGO_DATABASE = "runoobdb"
#pipeline启用
ITEM_PIPELINES = {
   'sinlangspider.pipelines.SinlangspiderPipeline': 300,
}

#设置UA
USER_AGENTS = [
    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
   ]
   

最后是使用scrapyd部署

首先安装scrapyd

pip install scrapyd

启动scrapyd:在命令行中输入srapyd就行了,默认情况下scrapyd运行后台会侦听6800端口。在浏览器中输入http://127.0.0.1:6800。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-owhjs8iB-1587900829322)(713A3D3014CF4AD08F5433F579C310B3)]

scrapyd使用json数据返回状态,所以其对应的指令如下

获取scrapyd状态:http://127.0.0.1:6800/daemonstatus.json.GET请求方式。
获取项目列表:http://127.00.1/6800/listprojects.json.GET请求方式。
获取项目下以发布的爬虫列表http://127.0.0.16800/listspiders.json?project=myproject.GET请求。项目名称为myproject。
获取已发布的爬虫版本列表。http://127.0.0.1:6800/listversion.json?project=myproject.GET请求。参数为项目名称project。
获取爬虫运行状态:http://127.0.0.1/6800/listjobs.json?project=myproject.GET请求,
启动服务器上的某一个爬虫:http://127.0.0.1:6800/schedule.json.POST请求方式,蚕食为:"project":myproject,'spider':myspider,myproject为项目名称,myspider为爬虫名称。
删除某一版本爬虫:http://127.0.0.1:6800/delversion.json.POST请求参数为''project':myproject,'version':myversion,myproject为项目名,version为爬虫版本。
删除某一工程,并将工程下各个版本爬虫一起删除。http://127.0.0.1:6800/delproject.json.POST请求方式,参数为'project':myproject,myproject为项目名称。
给工程添加版本,如果工程不存在则创建:http://127..0.1/6800/addversion.json.POST请求方式,参数为""project":myproject,'version':myversion,myproject为项目名称。version为项目版本。
取消一个运行的爬虫任务。http://127.0.0.1:6800/cancel.json.POST请求方式,参数为''project':myproject,'job':jobid,myproject为项目名称,jobid为任务id
scrapyd-client

scrapyd-client用于发布爬虫,首先安装

pip install scrapyd-client

使用scrapyd-client 安装完成后,将scrapyd-deploy拷贝到爬虫项目目录下,与scrapy.cfg在同一级目录。下面我们要修改scrapy.cfg文件,默认生成的scrapy.cfg文件内容如下:

[settings]
default = sinlangspider.settings

[deploy:100]
url = http://localhost:6800/
project = sinlang

deploy用于表示把爬虫发布到名为100的爬虫服务器上。一般在需要同时发去爬虫到多个目标服务器时使用。

配置完成后,就可以使用scrapy-deploy进行爬虫的发布。命令如下

scrapyd-deploy <target> -p sinlang --version ver2020426

版本如果不设置的话就会默认使用时间戳。

在部署爬虫前,要确认scrapyd启动了。

部署后启动爬虫:
在终端输入:

curl http://localhost:6800/schedule.json -d project=sinlang -d spider=slan

就此全部完成。
查看数据有100条
这个练手的小项目有很多的不足,仅仅满足基本需求。以后有机会会改进的。​

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值