国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁(yè) > news >正文

網(wǎng)站開(kāi)發(fā)進(jìn)度管理表谷歌seo工具

網(wǎng)站開(kāi)發(fā)進(jìn)度管理表,谷歌seo工具,哪個(gè)軟件制作視頻比較好,深圳做網(wǎng)站(龍華信科)python - 在linux上編譯py文件為【.so】文件,可通過(guò)主文件直接執(zhí)行 一. 前言 在Python中,通常不直接將Python代碼編譯為.so(共享對(duì)象)文件來(lái)執(zhí)行,因?yàn)?so文件是編譯后的二進(jìn)制代碼,通常用于C或C等語(yǔ)言&am…

python - 在linux上編譯py文件為【.so】文件,可通過(guò)主文件直接執(zhí)行

一. 前言

在Python中,通常不直接將Python代碼編譯為.so(共享對(duì)象)文件來(lái)執(zhí)行,因?yàn)?so文件是編譯后的二進(jìn)制代碼,通常用于C或C++等語(yǔ)言,并且它們被設(shè)計(jì)為可以被Python(通過(guò)C API)或其他語(yǔ)言(如C或C++)動(dòng)態(tài)加載和執(zhí)行。

二.打包編譯項(xiàng)目

準(zhǔn)備工作

一般linux上都會(huì)有GCC編譯器,如若沒(méi)有請(qǐng)先安裝
1.安裝Cython

pip install cython

2.將以下的腳本放在deploy目錄下,項(xiàng)目所有文件放在project下面即可
在這里插入圖片描述

1.編譯為.c文件的代碼

創(chuàng)建一個(gè)setup_cmd.py文件

import logging
import osfrom setuptools import setup
from Cython.Build import cythonize# ============================== 配置日志 ===============================
# 定義日志文件的名稱(chēng)
log_filename = 'setup_cmd.log'# 創(chuàng)建一個(gè)日志記錄器
logger = logging.getLogger()
logger.setLevel(logging.INFO)  # 設(shè)置日志級(jí)別為 INFO# 創(chuàng)建一個(gè)文件處理器,并設(shè)置級(jí)別為 INFO
file_handler = logging.FileHandler(log_filename, encoding='utf-8')  # 指定編碼為 utf-8
file_handler.setLevel(logging.INFO)# 創(chuàng)建一個(gè)流處理器(控制臺(tái)輸出),并設(shè)置級(jí)別為 INFO
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)# 創(chuàng)建日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
stream_handler.setFormatter(formatter)# 將處理器添加到日志記錄器
logger.addHandler(file_handler)
logger.addHandler(stream_handler)# ============================== 配置日志 ===============================
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # 設(shè)置 BASE_DIR
logger.info(f"BASE_DIR -> {BASE_DIR}\n")# 獲取需要編譯的文件列表
def get_py_files(directory, exclude_folders, exclude_file_list):py_files = []for root, dirs, files in os.walk(directory):for d in dirs:if d in exclude_folders:dirs.remove(d)for file in files:if file in exclude_file_list:logger.info(f"不需要編譯文件:[{file}] 在 {exclude_file_list} 中!")continueif file.endswith('.py') and '-' not in file:py_files.append(os.path.join(root, file))logger.info(f'py_files -> {py_files}')logger.info(f'py_files count -> {len(py_files)}')return py_filesexclude_folders = ['tests', '.git', '.idea', '__pycache__', 'a-deploy', 'deploy']
exclude_file_list = ['app.py']# 1.編譯打包
file_list = get_py_files(BASE_DIR, exclude_folders, exclude_file_list)
# 單個(gè)文件編譯或多個(gè)文件
# file_list = ['/opt/pkg/project/dev/service/sessionService/service_impl/nw_session_history.py']
setup(ext_modules=cythonize(file_list, language_level=3),  # 使用 Python 3 的語(yǔ)言級(jí)別
)

1.在linux環(huán)境下可直接執(zhí)行文件

python3 setup_cmd.py

2.windows上直接使用命令執(zhí)行

python3 setup_cmd.py build_ext --inplace
2.將.c文件轉(zhuǎn)化為.so文件

創(chuàng)建setup_compile_file.py文件
主要是將以下命令拆解執(zhí)行

gcc -pthread -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/usr/local/include/python3.11 -c /opt/pkg/project/dev/base/utils/handle_tasks.c -o build/temp.linux-x86_64-cpython-311/opt/pkg/project/dev/base/utils/handle_tasks.o
gcc -pthread -shared build/temp.linux-x86_64-cpython-311/opt/pkg/project/dev/base/utils/handle_tasks.o -o build/lib.linux-x86_64-cpython-311/handle_tasks.cpython-311-x86_64-linux-gnu.so

代碼如下,參考函數(shù):compile_c_files

# -*- coding: utf-8 -*-
import logging
import os
import shutil
import subprocessfrom setuptools import setup
from Cython.Build import cythonizeimport osfrom concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETEDexecutor = ThreadPoolExecutor(max_workers=50)# ============================== 配置日志 ===============================
# 定義日志文件的名稱(chēng)
log_filename = 'setup_compile_file.log'# 創(chuàng)建一個(gè)日志記錄器
logger = logging.getLogger()
logger.setLevel(logging.INFO)  # 設(shè)置日志級(jí)別為 INFO# 創(chuàng)建一個(gè)文件處理器,并設(shè)置級(jí)別為 INFO
file_handler = logging.FileHandler(log_filename, encoding='utf-8')  # 指定編碼為 utf-8
file_handler.setLevel(logging.INFO)# 創(chuàng)建一個(gè)流處理器(控制臺(tái)輸出),并設(shè)置級(jí)別為 INFO
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)# 創(chuàng)建日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
stream_handler.setFormatter(formatter)# 將處理器添加到日志記錄器
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
# ============================== 配置日志 ===============================# BASE_DIR = os.getcwd()
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # 設(shè)置 BASE_DIR
logger.info(f"BASE_DIR -> {BASE_DIR}\n")executor = ThreadPoolExecutor(max_workers=10)  # 根據(jù)需要調(diào)整線程數(shù)# 獲取需要編譯的文件列表
def get_py_files(directory, exclude_folders, exclude_file_list):py_files = []for root, dirs, files in os.walk(directory):for d in dirs:if d in exclude_folders:dirs.remove(d)for file in files:if file in exclude_file_list:logger.info(f"不需要編譯文件:[{file}] 在 {exclude_file_list} 中!")continueif file.endswith('.py') and '-' not in file:py_files.append(os.path.join(root, file))logger.info(f'py_files -> {py_files}')logger.info(f'py_files count -> {len(py_files)}')return py_files# 編譯擴(kuò)展模塊
def compile_pkg(file_list):setup(ext_modules=cythonize(file_list, language_level=3),  # 使用 Python 3 的語(yǔ)言級(jí)別)subprocess.run(['python3', 'setup_compile_file.py', 'build_ext', '--inplace'])#
def copy_compiled_files(source_dir, target_dir, exclude_folders, exclude_file_list):""" 拷貝處理編譯好的文件 """if os.path.exists(target_dir):shutil.rmtree(target_dir)logger.info(f"已刪除舊的目標(biāo)文件夾: {target_dir}")os.makedirs(target_dir)logger.info(f"已創(chuàng)建新的目標(biāo)文件夾: {target_dir}")ans = 0# 遍歷源文件夾  for root, dirs, files in os.walk(source_dir):# 過(guò)濾掉要排除的文件夾  dirs[:] = [d for d in dirs if d not in exclude_folders]# 遍歷當(dāng)前文件夾中的文件for file in files:try:if file in exclude_file_list:logger.info(f"不拷貝文件:[{file}] 在 exclude_file_list:{exclude_file_list} 中!")continue# 構(gòu)造源和目標(biāo)文件路徑src_file = os.path.join(root, file)rel_path = os.path.relpath(root, source_dir)dst_file = os.path.join(target_dir, rel_path, file)# 確保目標(biāo)文件夾存在os.makedirs(os.path.dirname(dst_file), exist_ok=True)# 拷貝文件shutil.copy2(src_file, dst_file)ans += 1logger.info(f'文件拷貝成功[src_file]:{src_file} -> [dst_file]:{dst_file}')except Exception as e:logger.info(f'文件拷貝異常:file:{file} -> error:{e}')logger.info(f"已成功拷貝編譯文件,數(shù)量:{ans}")def delete_specific_files(folder, extensions, exclude_file_list):"""在指定文件夾中刪除所有以extensions中指定的擴(kuò)展名結(jié)尾的文件。:param folder: 文件夾路徑:param extensions: 要?jiǎng)h除的文件擴(kuò)展名列表"""# 遍歷文件夾logger.info(f"")ans = 0for root, dirs, files in os.walk(folder):for file in files:if file in exclude_file_list:logger.info(f"不刪除文件:[{file}] 在 exclude_file_list:{exclude_file_list} 中!")continueif file.endswith(tuple(extensions)):os.remove(os.path.join(root, file))logger.info(f"已刪除含有 {extensions} 的文件: {os.path.join(root, file)}")ans += 1logger.info(f"已刪除以{extensions}結(jié)尾的文件數(shù)量:{ans}")def compile_c_files(target_dir, extensions, exclude_folders, exclude_file_list):"""編譯文件(linux下的命令)gcc -pthread -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/usr/local/include/python3.11 -c /opt/pkg/project/dev/base/utils/handle_tasks.c -o build/temp.linux-x86_64-cpython-311/opt/pkg/project/dev/base/utils/handle_tasks.ogcc -pthread -shared build/temp.linux-x86_64-cpython-311/opt/pkg/project/dev/base/utils/handle_tasks.o -o build/lib.linux-x86_64-cpython-311/handle_tasks.cpython-311-x86_64-linux-gnu.so"""# 遍歷文件夾ans = 0futures = []for root, dirs, files in os.walk(target_dir):for file in files:if file in exclude_file_list:logger.info(f"文件:{file} 在 exclude_file_list:{exclude_file_list} 中,不需要編譯!")continueif file.endswith(tuple(extensions)):c_path = os.path.join(root, file)file_name = file.split('.')[0]# o_path = root + '/' + file_name + '.o'o_path = os.path.join(root, file_name + '.o')# so_path = root + '/' + file_name + '.cpython-311-x86_64-linux-gnu.so'so_path = os.path.join(root, file_name + '.cpython-311-x86_64-linux-gnu.so')logger.info(f'c_path - > {c_path}')logger.info(f'o_path - > {o_path}')logger.info(f'so_path - > {so_path}')future = executor.submit(compile_file_to_so, c_path, o_path, so_path)futures.append(future)ans += 1logger.info(f'complied count -----> {ans}')# 等待所有任務(wù)完成wait(futures, return_when=ALL_COMPLETED)logger.info(f"已編譯文件數(shù)量:{ans}")def compile_file_to_so(c_path, o_path, so_path):os.system(f"gcc -pthread -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/usr/local/include/python3.11 -c {c_path} -o {o_path}")os.system(f"gcc -pthread -shared {o_path} -o {so_path}")logger.info(f'File success compiled to - > {so_path}')def main():exclude_folders = ['tests', '.git', '.idea', '__pycache__', 'a-deploy', 'deploy']exclude_file_list = ['app.py', 'app.c']logger.info(f'項(xiàng)目編譯打包開(kāi)始,源碼文件路勁:{BASE_DIR}\n')# try:#     # 單個(gè)文件編譯或多個(gè)文件#     # file_list = ['/opt/pkg/project/dev/service/sessionService/service_impl/nw_session_history.py']##     # 1.編譯打包#     file_list = get_py_files(BASE_DIR, exclude_folders, exclude_file_list)#     compile_pkg(file_list)#     ...# except Exception as e:#     logger.info(f'Exception:{e}')source_dir = BASE_DIRtarget_dir = os.path.join(BASE_DIR, 'deploy', 'dist')# 清除['.c']文件extensions = ['.c']logger.info(f'開(kāi)始清除項(xiàng)目中含有{extensions}結(jié)尾的文件 [target_dir]:{target_dir}\n')delete_specific_files(target_dir, extensions, exclude_file_list)logger.info(f'結(jié)束清除項(xiàng)目中含有{extensions}結(jié)尾的文件 [target_dir]:{target_dir}\n')# 2.復(fù)制編譯好的文件logger.info(f'復(fù)制拷貝項(xiàng)目開(kāi)始 [source_dir]:{source_dir} -> [target_dir]:{target_dir}\n')copy_compiled_files(source_dir, target_dir, exclude_folders, ['app.c'])logger.info(f'復(fù)制拷貝項(xiàng)目結(jié)束 [source_dir]:{source_dir} -> [target_dir]:{target_dir}\n')# # 3.刪除py文件# extensions = ['.py']# logger.info(f'開(kāi)始刪除拷貝項(xiàng)目中含有{extensions}結(jié)尾的文件 [target_dir]:{target_dir}\n')# delete_specific_files(target_dir, extensions, exclude_file_list)# logger.info(f'結(jié)束刪除拷貝項(xiàng)目中含有{extensions}結(jié)尾的文件 [target_dir]:{target_dir}\n')# 4.編譯項(xiàng)目['.c']文件 -> ['.so', 'pyd']compile_extensions = ['.c']logger.info(f"開(kāi)始編譯項(xiàng)目{compile_extensions}文件 ->  ['.so', 'pyd']\n")compile_c_files(target_dir, compile_extensions, exclude_folders, exclude_file_list)logger.info(f"結(jié)束編譯項(xiàng)目{compile_extensions}文件 ->  ['.so', 'pyd']\n")logger.info(f'項(xiàng)目編譯處理完成,源碼文件路勁:{source_dir}\n')logger.info(f'項(xiàng)目編譯處理完成,編譯打包文件路勁:{target_dir}\n')if __name__ == '__main__':main()
3.清理編譯后的項(xiàng)目文件

創(chuàng)建clean_compile_file.py文件

# -*- coding: utf-8 -*-
import loggingimport osfrom concurrent.futures import ThreadPoolExecutorexecutor = ThreadPoolExecutor(max_workers=50)# ============================== 配置日志 ===============================
# 定義日志文件的名稱(chēng)
log_filename = 'setup_compile_file.log'# 創(chuàng)建一個(gè)日志記錄器
logger = logging.getLogger()
logger.setLevel(logging.INFO)  # 設(shè)置日志級(jí)別為 INFO# 創(chuàng)建一個(gè)文件處理器,并設(shè)置級(jí)別為 INFO
file_handler = logging.FileHandler(log_filename, encoding='utf-8')  # 指定編碼為 utf-8
file_handler.setLevel(logging.INFO)# 創(chuàng)建一個(gè)流處理器(控制臺(tái)輸出),并設(shè)置級(jí)別為 INFO
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)# 創(chuàng)建日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
stream_handler.setFormatter(formatter)# 將處理器添加到日志記錄器
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
# ============================== 配置日志 ===============================# BASE_DIR = os.getcwd()
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # 設(shè)置 BASE_DIR
logger.info(f"BASE_DIR -> {BASE_DIR}\n")def delete_specific_files(folder, extensions, exclude_file_list):"""在指定文件夾中刪除所有以extensions中指定的擴(kuò)展名結(jié)尾的文件。:param folder: 文件夾路徑:param extensions: 要?jiǎng)h除的文件擴(kuò)展名列表"""# 遍歷文件夾logger.info(f"")ans = 0for root, dirs, files in os.walk(folder):for file in files:if file in exclude_file_list:logger.info(f"不刪除文件:[{file}] 在 exclude_file_list:{exclude_file_list} 中!")continueif file.endswith(tuple(extensions)):os.remove(os.path.join(root, file))logger.info(f"已刪除含有 {extensions} 的文件: {os.path.join(root, file)}")ans += 1logger.info(f"已刪除以{extensions}結(jié)尾的文件數(shù)量:{ans}")def main():exclude_folders = ['tests', '.git', '.idea', '__pycache__', 'a-deploy', 'deploy']exclude_file_list = ['app.py', 'app.c']logger.info(f'========= 項(xiàng)目編譯文件清理完成開(kāi)始 ========\n')target_dir = os.path.join(BASE_DIR, 'deploy', 'dist')# 刪除py文件extensions = ['.py', '.o', '.pyd', '.c']logger.info(f'開(kāi)始刪除拷貝項(xiàng)目中含有{extensions}結(jié)尾的文件 [target_dir]:{target_dir}\n')delete_specific_files(target_dir, extensions, exclude_file_list)logger.info(f'結(jié)束刪除拷貝項(xiàng)目中含有{extensions}結(jié)尾的文件 [target_dir]:{target_dir}\n')# # 刪除源碼下的['.so', 'pyd', '.c']文件# src_extensions = ['.so', 'pyd', '.c']# logger.info(f"開(kāi)始刪除源碼下的{src_extensions}文件\n")# delete_specific_files(source_dir, src_extensions)# logger.info(f"結(jié)束刪除源碼下的{src_extensions}文件\n")logger.info(f'========= 項(xiàng)目編譯文件清理完成!=========\n')if __name__ == '__main__':main()

其他操作

清理源代碼下的.c文件(可選)
clean_code_c_file.py

# -*- coding: utf-8 -*-
import loggingimport osfrom concurrent.futures import ThreadPoolExecutorexecutor = ThreadPoolExecutor(max_workers=50)# ============================== 配置日志 ===============================
# 定義日志文件的名稱(chēng)
log_filename = 'setup_compile_file.log'# 創(chuàng)建一個(gè)日志記錄器
logger = logging.getLogger()
logger.setLevel(logging.INFO)  # 設(shè)置日志級(jí)別為 INFO# 創(chuàng)建一個(gè)文件處理器,并設(shè)置級(jí)別為 INFO
file_handler = logging.FileHandler(log_filename, encoding='utf-8')  # 指定編碼為 utf-8
file_handler.setLevel(logging.INFO)# 創(chuàng)建一個(gè)流處理器(控制臺(tái)輸出),并設(shè)置級(jí)別為 INFO
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)# 創(chuàng)建日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
stream_handler.setFormatter(formatter)# 將處理器添加到日志記錄器
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
# ============================== 配置日志 ===============================# BASE_DIR = os.getcwd()
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # 設(shè)置 BASE_DIR
logger.info(f"BASE_DIR -> {BASE_DIR}\n")def delete_specific_files(folder, extensions, exclude_file_list):"""在指定文件夾中刪除所有以extensions中指定的擴(kuò)展名結(jié)尾的文件。:param folder: 文件夾路徑:param extensions: 要?jiǎng)h除的文件擴(kuò)展名列表"""# 遍歷文件夾logger.info(f"")ans = 0for root, dirs, files in os.walk(folder):for file in files:if file in exclude_file_list:logger.info(f"不刪除文件:[{file}] 在 exclude_file_list:{exclude_file_list} 中!")continueif file.endswith(tuple(extensions)):os.remove(os.path.join(root, file))logger.info(f"已刪除含有 {extensions} 的文件: {os.path.join(root, file)}")ans += 1logger.info(f"已刪除以{extensions}結(jié)尾的文件數(shù)量:{ans}")def main():exclude_folders = ['tests', '.git', '.idea', '__pycache__', 'a-deploy', 'deploy']exclude_file_list = ['app.py', 'app.c']logger.info(f'========= 項(xiàng)目編譯文件清理完成開(kāi)始 ========\n')source_dir = BASE_DIR# 刪除源碼下的['.so', 'pyd', '.c']文件src_extensions = ['.c']logger.info(f"開(kāi)始刪除源碼下的{src_extensions}文件\n")delete_specific_files(source_dir, src_extensions, exclude_file_list)logger.info(f"結(jié)束刪除源碼下的{src_extensions}文件\n")logger.info(f'========= 項(xiàng)目源碼文件清理完成!=========\n')if __name__ == '__main__':main()

shell腳本

start_setup.sh

#!/bin/bashecho "開(kāi)始執(zhí)行 setup_cmd.py ..."
python3 setup_cmd.py
echo "setup_cmd.py 執(zhí)行完成!"echo "開(kāi)始執(zhí)行 setup_compile_file.py ..."
python3 setup_compile_file.py
if [ $? -eq 0 ]; thenecho "setup_compile_file.py 中的所有任務(wù)執(zhí)行成功完成!"
elseecho "setup_compile_file.py 執(zhí)行失敗或任務(wù)未完成,請(qǐng)檢查錯(cuò)誤。"exit 1
fi# 等待 setup_compile_file.py 中的所有線程完成后,執(zhí)行 clean_compile_file.py
echo "開(kāi)始執(zhí)行 clean_compile_file.py ..."
python3 clean_compile_file.py
if [ $? -eq 0 ]; thenecho "clean_compile_file.py 執(zhí)行成功!"
elseecho "clean_compile_file.py 執(zhí)行失敗,請(qǐng)檢查錯(cuò)誤。"exit 1
fiecho "所有腳本執(zhí)行完畢。"

Cython只是幫助我們將Python代碼(或Python風(fēng)格的代碼)轉(zhuǎn)換成了C代碼,然后編譯成了二進(jìn)制形式。這個(gè)過(guò)程并不是傳統(tǒng)意義上的“編譯Python代碼為機(jī)器碼執(zhí)行”,而是利用了C的編譯效率和Python的易用性之間的平衡。

本文介紹到此結(jié)束,希望對(duì)你有所幫助!

http://aloenet.com.cn/news/32813.html

相關(guān)文章:

  • 太原網(wǎng)站建設(shè)費(fèi)用上首頁(yè)seo
  • 網(wǎng)站一般寬度windows優(yōu)化大師有哪些功能
  • 國(guó)內(nèi) 設(shè)計(jì)網(wǎng)站的公司網(wǎng)站3000行業(yè)關(guān)鍵詞
  • 手機(jī)網(wǎng)站開(kāi)發(fā)教程?hào)|莞做網(wǎng)站哪家公司好
  • 網(wǎng)站有沒(méi)有做網(wǎng)站地圖怎么看今天國(guó)際新聞大事
  • 想做一個(gè)自己設(shè)計(jì)公司的網(wǎng)站怎么做的網(wǎng)站推廣公司電話
  • 電腦做系統(tǒng)網(wǎng)站鄭州網(wǎng)站優(yōu)化培訓(xùn)
  • 軟件工程師是程序員嗎電腦優(yōu)化工具
  • 建設(shè)一個(gè)大型網(wǎng)站大概費(fèi)用磁力王
  • 主流門(mén)戶(hù)網(wǎng)站百度關(guān)鍵詞搜索推廣
  • 怎樣設(shè)計(jì)網(wǎng)頁(yè)教程關(guān)鍵詞優(yōu)化外包
  • 鄭州電力高等專(zhuān)科學(xué)校哪個(gè)專(zhuān)業(yè)好重慶seo和網(wǎng)絡(luò)推廣
  • 可視化網(wǎng)站制作軟件站長(zhǎng)之家ppt素材
  • 深圳html5網(wǎng)站建設(shè)搜索引擎營(yíng)銷(xiāo)sem
  • 遼寧網(wǎng)站推廣的目的網(wǎng)絡(luò)運(yùn)營(yíng)是做什么的工作
  • 做外國(guó)網(wǎng)站買(mǎi)域名推廣賺錢(qián)一個(gè)2元
  • 網(wǎng)站建設(shè)后期維護(hù)小魔仙網(wǎng)絡(luò)廣告宣傳平臺(tái)
  • 企業(yè)網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃方案范文免費(fèi)seo教程資源
  • wordpress 添加搜索引擎北京網(wǎng)絡(luò)seo
  • 三合一網(wǎng)站建設(shè)方案深圳市網(wǎng)絡(luò)營(yíng)銷(xiāo)推廣服務(wù)公司
  • b2b網(wǎng)站建設(shè)開(kāi)發(fā)china東莞seo
  • 網(wǎng)站的服務(wù)有哪些seo外鏈工具有用嗎
  • 南陽(yáng)網(wǎng)站建設(shè)大旗電商電商網(wǎng)站訂煙
  • wordpress投訴功能qq群怎么優(yōu)化排名靠前
  • 多媒體網(wǎng)站開(kāi)發(fā)實(shí)驗(yàn)報(bào)告做企業(yè)網(wǎng)站建設(shè)的公司
  • 網(wǎng)頁(yè)搜索工具新站seo優(yōu)化快速上排名
  • wordpress推廣升級(jí)vipseo做什么網(wǎng)站賺錢(qián)
  • 學(xué)網(wǎng)站建設(shè)怎么樣tool站長(zhǎng)工具
  • 網(wǎng)站的懲罰期要怎么做廣告安裝接單app
  • 國(guó)外設(shè)計(jì)網(wǎng)站dooor企業(yè)營(yíng)銷(xiāo)策劃書(shū)模板