Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
import random
import re
import time
import xlsxwriter
from selenium import webdriver
from lxml import etree
import requests
# ua池
ua_list=[
"Mozilla/5.0 (Windows NT 10.0; Win64; x32) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.39 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.26 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36",
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Safari/537.36',
'Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X; zh-CN) AppleWebKit/537.51.1 (KHTML, like Gecko) Mobile/17D50 UCBrowser/12.8.2.1268 Mobile AliApp(TUnionSDK/0.1.20.3)',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36',
'Mozilla/5.0 (Linux; Android 8.1.0; OPPO R11t Build/OPM1.171019.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/11.19 SP-engine/2.15.0 baiduboxapp/11.19.5.10 (Baidu; P1 8.1.0)',
'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
'Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 SP-engine/2.14.0 main%2F1.0 baiduboxapp/11.18.0.16 (Baidu; P2 13.3.1) NABar/0.0',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134',
'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
]
ua=random.choice(ua_list)
# Ip池
proxy_list=[
{"http" or "https": "124.71.14.222:10002"},
{"http" or "https": '60.167.133.17:1133'},
{"http" or "https": '183.0.203.167:8118'},
{"http" or "https": '111.231.86.149:7890'},
{"http" or "https": "183.0.203.167:8118"},
{"http" or "https": '163.125.222.12:8118'},
{"http" or "https": '111.59.199.58:8118'},
]
proxies=random.choice(proxy_list)
word=input('請(qǐng)輸入你要獲取的商品:', )
page=input('請(qǐng)輸入商品頁(yè)數(shù):',)
# 獲取商品鏈接和id
def get_link():
links=[]
skus_id=[]
for i in range(int(page)):
url=f'https://search.jd.com/Search?keyword={word}&wq={word}&page={i}'
headers={
"user-agent": ua,
}
res=requests.get(url=url, headers=headers, proxies=proxies).text
time.sleep(0.5)
# print(res)
# 提取商品鏈接并進(jìn)行拼接操作
html=etree.HTML(res)
link=html.xpath('//*[@id="J_goodsList"]/ul/li[*]/div/div[3]/a/@href')
link=['https:' + k for k in link]
for l in link:
links.append(l)
# 提取商品id
sku_id=[re.findall('\d+', i)[0] for i in link]
for s in sku_id:
skus_id.append(s)
print(f'第{i+1}頁(yè)。')
print(links)
goods(links, skus_id)
# 獲取商品詳情
def goods(links, skus_id):
goo=[]
pict=0
for i in range(len(links)):
headers={
"User-Agent": ua,
'referer': 'https://search.jd.com/',
}
res=requests.get(url=links[i], headers=headers, proxies=proxies).text
time.sleep(2)
# print(res)
html=etree.HTML(res)
# 店鋪名稱
title=html.xpath('//*[@id="crumb-wrap"]/div/div[2]/div[2]/div[1]/div/a/@title')
print(title)
# 品牌
brand=html.xpath('//*[@id="parameter-brand"]/li/@title')
print(brand)
# 商品編號(hào)
serial=html.xpath('//*[@id="detail"]/div[2]/div[1]/div[1]/ul[2]/li[2]/text()')
serial=[serial[0].split(':')[-1]]
print(serial)
# 正式商品名稱
official=html.xpath('//*[@id="detail"]/div[2]/div[1]/div[1]/ul[2]/li[1]/text()')
official=[official[0].split(':')[-1].strip()]
print(official)
# 網(wǎng)頁(yè)商品名稱
name=html.xpath('/html/body/div[6]/div/div[2]/div[1]/text()')
if len(name)==1:
name=[name[0].strip()]
elif len(name)==2:
name=[name[1].strip()]
print(name)
# 商品第一張主圖片
picture=['https:' + html.xpath('//*[@id="spec-img"]/@data-origin')[0]]
print(picture)
res2=requests.get(url=picture[0], headers=headers)
with open(f'D:\pythonproject\python項(xiàng)目爬蟲\接單\京東商品評(píng)價(jià)獲取(接單考核)\商品圖片/{pict}.jpg', 'wb')as f:
f.write(res2.content)
pict +=1
# 京東價(jià),請(qǐng)求價(jià)格信息json
p=requests.get('https://p.3.cn/prices/mgets?skuIds=J_' + skus_id[i], headers=headers, proxies=proxies).text
print(p)
price=re.findall('"p":"(.*?)","op"', p)
print(price)
# 優(yōu)惠劵和促銷
options=webdriver.ChromeOptions()# 無界面模式
options.add_argument('--headless')
driver=webdriver.Chrome(options=options)
driver.get(links[i])
time.sleep(1)
# 獲取源代碼
data=driver.page_source
time.sleep(0.5)
driver.close()
driver.quit()
# 促銷
html2=etree.HTML(data)
promotion1=html2.xpath('//*[@id="prom"]/div/div[1]/em[2]/text()')
promotion2=html2.xpath('//*[@id="prom"]/div/div[2]/em[2]/text()')
if promotion1==[] and promotion2==[]:
promotion=['暫無促銷信息']
elif promotion1==[] and promotion2 !=[]:
promotion=promotion2
elif promotion2==[] and promotion1 !=[]:
promotion=promotion1
else:
promotion=[promotion1[0], promotion2[0]]
print(promotion)
# 優(yōu)惠劵信息
coupon=html2.xpath('//*[@id="summary-quan"]/div[2]/dl/dd/a/span/span/text()')
if coupon==[]:
coupon=['暫無可領(lǐng)的優(yōu)惠券']
print(coupon)
# 累計(jì)評(píng)價(jià)
comm_url=f'https://club.jd.com/comment/productCommentSummaries.action?referenceIds={skus_id[i]}'
comment_headers={
'user-agent': ua,
}
res_js=requests.get(url=comm_url, headers=comment_headers, proxies=proxies).text
comment=re.findall('"CommentCountStr":"(.*?)","CommentCount":', res_js)
print(comment)
for g in zip(title, brand, serial, official, name, price, promotion, coupon, comment, picture):
goo.append(g)
print(f'第{i+1}件商品打印完成。')
print(goo)
save(goo)
5.數(shù)據(jù)保存,并通過xlsxwrite進(jìn)行圖片保存
# 數(shù)據(jù)保存
def save(goo):
# 創(chuàng)建工作簿
workbook=xlsxwriter.Workbook('京東商品詳情.xlsx')
# 創(chuàng)建工作表
worksheet=workbook.add_worksheet(word)
# 大部分樣式如下:
format={
# 'font_size': 10, # 字體大小
'bold': True, # 是否粗體
# 'bg_color': '#101010', # 表格背景顏色
# 'fg_color': '#00FF00',
# 'font_color': '#0000FF', # 字體顏色
'align': 'center', # 水平居中對(duì)齊
'valign': 'vcenter', # 垂直居中對(duì)齊
# 'num_format': 'yyyy-mm-dd H:M:S',# 設(shè)置日期格式
# 后面參數(shù)是線條寬度
'border': 1, # 邊框?qū)挾?/p>
'top': 1, # 上邊框
'left': 1, # 左邊框
'right': 1, # 右邊框
'bottom': 1 # 底邊框
}
style=workbook.add_format(format)
# 寫入圖片
a=0
worksheet.set_column(9, 9, 350) # 設(shè)置列寬
for i in range(len(goo)):
worksheet.set_row(i + 1, 350) # 設(shè)置行高350
worksheet.insert_image(i + 1, 9, f'D:\pythonproject\python項(xiàng)目爬蟲\接單\京東商品評(píng)價(jià)獲取(接單考核)\商品圖片/{a}.jpg', {'url': goo[i][-1]})
a +=1
# 寫入數(shù)據(jù)
col=('店鋪名稱', '品牌', '商品編號(hào)', '正式商品名稱', '網(wǎng)頁(yè)商品名稱', '京東價(jià)', '促銷', '優(yōu)惠劵', '累計(jì)評(píng)價(jià)', '商品第一張主圖片',)
for i in range(len(col)):
worksheet.write(0, i, col[i])
for i in range(len(goo)):
for c in range(len(col) - 1):
worksheet.write(i + 1, c, goo[i][c], style)
workbook.close()
6.開啟程序
if __name__=='__main__':
get_link()
原文鏈接:https://blog.csdn.net/weixin_62871152/article/details/121457846
開始之前,做一點(diǎn)小小的說明哈:
首先打開網(wǎng)易云的網(wǎng)頁(yè)版網(wǎng)易云
然后搜索歌曲,這里我就搜索一首錦零的“空山新雨后”
這時(shí)我們來觀察網(wǎng)頁(yè)的url,可以發(fā)現(xiàn)s=后面就是我們搜索的關(guān)鍵字
當(dāng)我們換一首歌,會(huì)發(fā)現(xiàn)也是這樣的,正好驗(yàn)證了我們的想法
所以下一步讓我們點(diǎn)進(jìn)去一首歌,然后進(jìn)行播放,看看能否直接獲取音樂文件的url,如果能,那么直接對(duì)url進(jìn)行requests.get訪問,我們就能拿到.mp3文件了
點(diǎn)進(jìn)第一首“空山新雨后”,我們可以看到有一個(gè)“生成外鏈播放器”
看到這個(gè),我心中一陣激動(dòng),仿佛就要大功告成;于是我滿懷開心的點(diǎn)了一下,結(jié)果。。。
好吧,不過我們不能放棄,來我們分析一下網(wǎng)頁(yè)
但當(dāng)我們定位到兩個(gè)最有可能出現(xiàn)外鏈的地方時(shí),發(fā)現(xiàn)什么都沒有
不過作為“規(guī)格嚴(yán)格,功夫到家”的傳承者,我不能放棄啊,于是我又打開了抓包工具
按照常規(guī)套路,我們定位到XHR
點(diǎn)擊播放后,出現(xiàn)了一大堆東西,我們要做的就是找到其中的content-type為audio一類的包
功夫不負(fù)有心人,在尋找了一(億)會(huì)兒后,我找到了
于是我又滿懷開心的復(fù)制了這個(gè)包對(duì)應(yīng)的Request-URL
粘貼后訪問這個(gè)url,結(jié)果非常滿意,這就是我一直在找的url
現(xiàn)在我把那個(gè)url貼出來
https://m10.music.126.net/20200715163315/a075d787d191f6729a517527d6064f59/ymusic/0552/0f0e/530f/28d03e94478dcc3e0479de4b61d224e9.mp3
接下來就超級(jí)簡(jiǎn)單了
下面的代碼是最常規(guī)的操作,應(yīng)該有爬蟲基礎(chǔ)的都能看懂;如果有不懂的,注釋都在上面
#導(dǎo)入requests包
import requests
#進(jìn)行UA偽裝
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36'
}
#指定url
url='https://m10.music.126.net/20200715163315/a075d787d191f6729a517527d6064f59/ymusic/0552/0f0e/530f/28d03e94478dcc3e0479de4b61d224e9.mp3'
#調(diào)用requests.get方法對(duì)url進(jìn)行訪問,和持久化存儲(chǔ)數(shù)據(jù)
audio_content=requests.get(url=url,headers=headers).content
#存入本地
with open('空山新雨后.mp3','wb') as f :
f.write(audio_content)
print("空山新雨后爬取成功!!!")
看到這里,你可能會(huì)想,為啥根本沒用selenium模塊呢?能不能直接爬取任何一首我想要的歌,而不用每首都去費(fèi)心費(fèi)力的找一個(gè)url呢?當(dāng)然可以噠!
其實(shí)網(wǎng)易云在線播放每首歌曲時(shí),都有一個(gè)外鏈地址,這是不會(huì)變的,跟每首歌的唯一一個(gè)id綁定在一起,每首歌audio文件的url如下:
url='http://music.163.com/song/media/outer/url?id=' + 歌曲的id值 + '.mp3'
id值的獲取也很簡(jiǎn)單,當(dāng)我們點(diǎn)進(jìn)每首歌時(shí),上方會(huì)出現(xiàn)對(duì)應(yīng)的網(wǎng)址,那里有id值,如下圖:
所以只需把上面程序中的url改成新的url即可
如果還想要更好的體驗(yàn)效果,實(shí)現(xiàn)在程序里直接搜索歌曲,拿到id值,就需要用到selenium模塊
為什么用selenium而不用xpath或bs4?
因?yàn)樗阉黜?yè)面的數(shù)據(jù)是動(dòng)態(tài)加載出來的,如果直接對(duì)搜索頁(yè)面的網(wǎng)頁(yè)進(jìn)行數(shù)據(jù)解析,就拿不到任何數(shù)據(jù);以我目前的技術(shù),就只能想到使用萬能的selenium模塊,下面大概說明一下步驟:
from selenium.webdriver.chrome.options import Options
chrome_options=Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
import requests
import re
from selenium import webdriver
from time import sleep
name=input('請(qǐng)輸入歌名:')
url_1='https://music.163.com/#/search/m/?s=' + name + '&type=1'
#初始化browser對(duì)象
browser=webdriver.Chrome(executable_path='chromedriver.exe',chrome_options=chrome_options)
#訪問該url
browser.get(url=url_1)
#由于網(wǎng)頁(yè)中有iframe框架,進(jìn)行切換
browser.switch_to.frame('g_iframe')
#等待0.5秒
sleep(0.5)
#抓取到頁(yè)面信息
page_text=browser.execute_script("return document.documentElement.outerHTML")
#退出瀏覽器
browser.quit()
ex1='<a.*?id="([0-9]*?)"'
ex2='<b.*?title="(.*?)"><span class="s-fc7">'
ex3='class="td w1"><div.*?class="text"><a.*?href=".*?">(.*?)</a></div></div>'
id_list=re.findall(ex1,page_text,re.M)[::2]
song_list=re.findall(ex2,page_text,re.M)
singer_list=re.findall(ex3,page_text,re.M)
li=list(zip(song_list,singer_list,id_list))
for i in range(len(li)):
print(str(i+1) + '.' + str(li[i]),end='\n')
終究是我才疏學(xué)淺,這個(gè)找外鏈進(jìn)行爬取的方法也存在很多不足,比如不能在線播放的歌曲是無法下載的。
不過寫這樣一個(gè)小程序練練手,對(duì)自己能力的提高確是有極大幫助的。
Python 和 JavaScript 是兩種廣泛應(yīng)用于 Web 開發(fā)的重要編程語言,在日常的 Web 開發(fā)和 Web 數(shù)據(jù)處理中,我們經(jīng)常需要使用這兩種語言。
例如,在 Web 端爬蟲過程中,我們可能會(huì)遇到需要解密網(wǎng)頁(yè)源代碼的情況,這時(shí)就需要一層一層剝離關(guān)鍵的 JS 代碼,并使用 Python 執(zhí)行這段代碼以獲取關(guān)鍵信息。
那么,Python 如何調(diào)用 JS 呢?有哪些方式呢?
以一段簡(jiǎn)單的JS腳本(add.js)為例,計(jì)算兩個(gè)數(shù)的和。
// JavaScript 示例代碼
function add(a, b) {
return a + b;
}
使用 Python 的os.popen或subprocess執(zhí)行 node 命令,執(zhí)行 JS 腳本。
首先,確保本地已經(jīng)安裝了 Node.js 環(huán)境:
> node -v
v18.16.1
修改 JS 腳本,新增一個(gè)導(dǎo)出函數(shù) init ,方便內(nèi)部函數(shù)被調(diào)用:
// JavaScript 示例代碼
function add(a, b) {
return a + b;
}
// 新增一個(gè)導(dǎo)出函數(shù)(node方式)
module.exports.init=function (arg1, arg2) {
// 調(diào)用函數(shù),并返回
console.log(add(arg1, arg2));
};
// 調(diào)用 init 方法并傳遞參數(shù)
module.exports.init(parseInt(process.argv[3]), parseInt(process.argv[4]));
使用subprocess模擬node.js命令行調(diào)用并獲取結(jié)果:
import subprocess
from loguru import logger
if __name__=='__main__':
# 使用 subprocess 模塊執(zhí)行 Node.js 命令
result=subprocess.run(["node", "add.js", "init", "3", "5"], capture_output=True, text=True)
# 輸出執(zhí)行結(jié)果
logger.info(f"Node.js 執(zhí)行結(jié)果: {result.stdout.strip()}")
PyExecJS 是使用最多的一種方式,底層實(shí)現(xiàn)方式是本地 JS 環(huán)境下運(yùn)行 JS 代碼,支持的 JS 環(huán)境包含:Node.js、PhantomJS 等。
首先第一步安裝:
pip install PyExecJS==1.5.1
安裝完成之后,即可以使用其調(diào)用 JS 腳本:
#! -*-conding=: UTF-8 -*-
from loguru import logger
import execjs
# 定義 JavaScript 代碼
# js_code="""
# function add(a, b) {
# return a + b;
# }
# """
if __name__=='__main__':
# Python 示例代碼
js_code=open("add.js", "r", encoding="utf-8").read()
# 使用 PyExecJS 執(zhí)行 JavaScript 代碼
ctx=execjs.compile(js_code)
# 調(diào)用 JavaScript 函數(shù),并計(jì)算結(jié)果
result=ctx.call("add", 3, 5)
logger.info(f"調(diào)用 JavaScript 函數(shù)的結(jié)果為: {result}")
DrissionPage方式
這款工具既能控制瀏覽器,也能收發(fā)數(shù)據(jù)包,甚至能把兩者合而為一。
首先安裝依賴庫(kù):
pip install DrissionPage==4.0.4.22
執(zhí)行 JS 腳本:
#! -*-conding=: UTF-8 -*-
from DrissionPage import ChromiumPage
if __name__=='__main__':
page=ChromiumPage()
# 打開網(wǎng)頁(yè)
page.get("about:blank")
# 定義 JavaScript 代碼
js_code="""
function add(a, b) {
return a + b;
}
"""
# 在當(dāng)前頁(yè)面上執(zhí)行 JavaScript 代碼,并傳遞參數(shù)
result=page.run_js(js_code + " return add(8, 5)")
# 輸出執(zhí)行結(jié)果
print("JavaScript 執(zhí)行結(jié)果:", result) # JavaScript 執(zhí)行結(jié)果: 13
page.quit()
playwright方式
Playwright 是一個(gè)用于 Web 測(cè)試和自動(dòng)化的框架。
首先安裝依賴庫(kù):
pip install playwright==1.43.0
playwright install # 安裝驅(qū)動(dòng)
執(zhí)行 JS 腳本:
#! -*-conding=: UTF-8 -*-
from playwright.sync_api import sync_playwright
if __name__=='__main__':
# 啟動(dòng) Playwright
with sync_playwright() as p:
# 啟動(dòng) Chromium 瀏覽器
browser=p.chromium.launch(headless=False)
# 創(chuàng)建新頁(yè)面
page=browser.new_page()
# 打開網(wǎng)頁(yè)
page.goto("https://baidu.com")
# 定義 JavaScript 代碼
js_code="""
function add(a, b) {
return a + b;
}
"""
page.add_script_tag(content=js_code) # 使用 page.add_script_tag() 方法將其注入到頁(yè)面中,然后在頁(yè)面上執(zhí)行它
# 在當(dāng)前頁(yè)面上執(zhí)行 JavaScript 代碼
result=page.evaluate("add(5, 7)")
# 輸出執(zhí)行結(jié)果
print("JavaScript 執(zhí)行結(jié)果:", result) # JavaScript 執(zhí)行結(jié)果: 12
# 關(guān)閉瀏覽器
browser.close()
selenium方式
Selenium是一個(gè)用于測(cè)試網(wǎng)站的自動(dòng)化測(cè)試工具,支持各種瀏覽器包括 Chrome、Firefox、Safari 等主流界面瀏覽器和 phantomJS 無界面瀏覽器。
首先安裝依賴庫(kù):
pip install selenium==4.20.0
執(zhí)行 JS 腳本:
#! -*-conding=: UTF-8 -*-
from selenium import webdriver
# 啟動(dòng) Chrome 瀏覽器
driver=webdriver.Chrome()
# 打開網(wǎng)頁(yè)
driver.get("about:blank")
# 定義 JavaScript 代碼
js_code="""
function add(a, b) {
return a + b;
}
"""
# 在當(dāng)前頁(yè)面上執(zhí)行 JavaScript 代碼,并傳遞參數(shù)
result=driver.execute_script(js_code + " return add(3, 5)")
# 輸出執(zhí)行結(jié)果
print("JavaScript 執(zhí)行結(jié)果:", result)
# 關(guān)閉瀏覽器
driver.quit()
類似的自動(dòng)化工具還有很多,如果只是單純的調(diào)用 JS 腳本,屬實(shí)有點(diǎn)殺雞用牛刀的趕jio。
Js2Py 作為一個(gè)純 Python 實(shí)現(xiàn)的 JS 解釋器,可以完全脫離 JS 環(huán)境,直接將 JS 代碼轉(zhuǎn)換為 Python 代碼。
首先第一步安裝:
pip install Js2Py==0.74
調(diào)用 JS 腳本:
#! -*-conding=: UTF-8 -*-
from js2py import eval_js
if __name__=='__main__':
# JavaScript 示例代碼
js_code="""
function add(a, b) {
return a + b;
}
"""
# 執(zhí)行 JavaScript 代碼
result=eval_js(js_code + "add(3, 5)")
# 輸出執(zhí)行結(jié)果
print("JavaScript 執(zhí)行結(jié)果:", result)
PyMiniRacer 是一個(gè) Python 模塊,它提供了一個(gè)輕量級(jí)、快速且安全的方式來執(zhí)行 JavaScript 代碼,無需借助完整的 V8 引擎或 Node.js 環(huán)境。
不知道佬們用的多不多,據(jù)說速度比PyExecJS快不少。
直接安裝:
pip install py_mini_racer==0.6.0
運(yùn)行:
#! -*-conding=: UTF-8 -*-
from py_mini_racer import MiniRacer
if __name__=='__main__':
# 創(chuàng)建 PyMiniRacer 實(shí)例
ctx=MiniRacer()
js_code="""
function add(a, b) {
return a + b;
}
"""
# 在 JavaScript 環(huán)境中執(zhí)行代碼并傳遞參數(shù)
ctx.eval(js_code)
result=ctx.call("add", 3, 5)
# 輸出執(zhí)行結(jié)果
print("JavaScript 執(zhí)行結(jié)果:", result) # JavaScript 執(zhí)行結(jié)果: 8
Python 中執(zhí)行和調(diào)用 JavaScript 代碼有多種方法:
每種工具都有其適用的場(chǎng)景和局限性,選擇合適的工具取決于具體的需求和項(xiàng)目要求。
原文鏈接:https://juejin.cn/post/7367701663169790002
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。