当前位置: 首页 > news >正文

做vr网站html网页设计代码范例

做vr网站,html网页设计代码范例,深圳市网站建设科技,网站域名如何影响seo编者按#xff1a; 自 2023 年以来#xff0c;RAG 已成为基于 LLM 的人工智能系统中应用最为广泛的架构之一。由于诸多产品的关键功能#xff08;如#xff1a;领域智能问答、知识库构建等#xff09;严重依赖RAG#xff0c;优化其性能、提高检索效率和准确性迫在眉睫 自 2023 年以来RAG 已成为基于 LLM 的人工智能系统中应用最为广泛的架构之一。由于诸多产品的关键功能如领域智能问答、知识库构建等严重依赖RAG优化其性能、提高检索效率和准确性迫在眉睫成为当前 RAG 相关研究的核心问题。如何高效准确地从PDF等非结构化数据中提取信息并加以利用是其中一个亟待解决的重要问题。本文比较分析了多种解决方案的优缺点着重探讨了这一问题的应对之策。 文章首先介绍了基于规则的解析方法如pypdf指出其无法很好地保留文档结构。接着作者评估了基于深度学习模型的解析方法如 Unstructured 和 Layout-parser 阐述了这种方法在提取表格、图像和保留文档布局结构等方面的优势但同时也存在一些局限性。对于具有双列double-column等复杂布局的 PDF 文档作者提出了一种经过改进的重排序算法。此外作者还探讨了利用多模态大模型直接从 PDF 文档中提取信息的可能性。 这篇文章系统地分析了 PDF 文档解析中的各种挑战并给出了一系列解决思路和改进算法为进一步提高非结构化数据解析的质量贡献了有价值的见解同时也指出了未来 PDF 文档解析的发展方向。 作者 | Florian June 编译 | 岳扬 对于 RAG 系统而言从文档中提取信息是一种不可避免的情况。确保能够从源文件中有效地提取内容对于提高最终输出的质量至关重要。 切勿低估这一流程的重要性。在使用 RAG 系统时如果在文档解析过程中信息提取不力会导致对 PDF 文件中所含信息的理解和利用受限。 解析流程Pasing process在 RAG 系统中的位置如图 1 所示 图 1解析流程Pasing process在 RAG 系统中的位置。Image by author。 在实际工作场景中非结构化数据远比结构化数据丰富。但如果这些海量数据不能被解析其巨大价值将无法发掘其中 PDF 文档尤为突出。 在非结构化数据中PDF 文档占绝大多数。有效处理 PDF 文档对管理其他类型的非结构化文档也有很大帮助。 本文主要介绍解析 PDF 文档的方法包括但不限于如何有效解析 PDF 文档、如何尽可能提取更多有用信息等相关问题的算法和建议。 01 解析 PDF 将会面临的挑战 PDF 文档是非结构化文档的代表性格式然而从 PDF 文档中提取信息是一个极具挑战性的过程。 与其说 PDF 是一种数据格式不如将其描述为一系列打印指令的集合更为准确。PDF 文件由一系列指令组成这些指令指示 PDF 阅读器或打印机在屏幕或纸张上如何安排各种符号、文字的位置和显示方式。 这与 HTML 和 docx 等文件格式截然不同这些文件格式使用 p、w:p、table 和 w:tbl 等标签来组织不同的逻辑结构如图 2 所示 图 2Html vs PDF. Image by author. 解析 PDF 文档的挑战在于准确提取整个页面的布局并将所有内容包括表格、标题、文本段落和图像转化为文本形式。 在这个过程中会出现文本提取不准确、图像识别不精确以及混淆表格中的行列关系等挑战。 02 如何解析 PDF 文档 一般来说解析 PDF 文档有三种方法它们各有优缺点适用于不同的场景 基于规则的解析方法Rule-based approach 根据文档的组织特征确定 PDF 文档中每个部分的样式和内容。不过这种方法的通用性不强因为 PDF 的类型和布局繁多难以通过预定义的规则覆盖所有情况。基于深度学习模型的解析方法例如结合目标检测object detection和 OCR 模型的解决方案。基于多模态大模型解析复杂结构或提取 PDF 中的关键信息。 2.1 基于规则的解析方法Rule-based approach pypdf[1] 是这种方法最具代表性的工具之一它是一种被广泛使用的基于规则的 PDF 解析工具。在 LangChain[2] 和 LlamaIndex[3] 等库中被作为解析 PDF 文件的标准方法使用。 下面是使用 pypdf 尝试解析《Attention Is All You Need》[4]论文第 6 页的案例。该页面如图 3 所示。 图 3《Attention Is All You Need》论文第 6 页 具体代码如下 import PyPDF2 filename /Users/Florian/Downloads/1706.03762.pdf pdf_file open(filename, rb)reader PyPDF2.PdfReader(pdf_file)page_num 5 page reader.pages[page_num] text page.extract_text()print(--------------------------------------------------) print(text)pdf_file.close()代码运行结果为为简洁起见省略其余部分 (py) Florian:~ Florian$ pip list | grep pypdf pypdf 3.17.4 pypdfium2 4.26.0(py) Florian:~ Florian$ python /Users/Florian/Downloads/pypdf_test.py -------------------------------------------------- Table 1: Maximum path lengths, per-layer complexity and minimum number of sequential operations for different layer types. nis the sequence length, dis the representation dimension, kis the kernel size of convolutions and rthe size of the neighborhood in restricted self-attention. Layer Type Complexity per Layer Sequential Maximum Path Length Operations Self-Attention O(n2·d) O(1) O(1) Recurrent O(n·d2) O(n) O(n) Convolutional O(k·n·d2) O(1) O(logk(n)) Self-Attention (restricted) O(r·n·d) O(1) O(n/r) 3.5 Positional Encoding Since our model contains no recurrence and no convolution, in order for the model to make use of the order of the sequence, we must inject some information about the relative or absolute position of the tokens in the sequence. To this end, we add positional encodings to the input embeddings at the bottoms of the encoder and decoder stacks. The positional encodings have the same dimension dmodel as the embeddings, so that the two can be summed. There are many choices of positional encodings, learned and fixed [9]. In this work, we use sine and cosine functions of different frequencies: PE(pos,2i)sin(pos/100002i/d model) PE(pos,2i1)cos(pos/100002i/d model) where posis the position and iis the dimension. That is, each dimension of the positional encoding corresponds to a sinusoid. The wavelengths form a geometric progression from 2πto10000 ·2π. We chose this function because we hypothesized it would allow the model to easily learn to attend by relative positions, since for any fixed offset k,PEposkcan be represented as a linear function of PEpos. ... ... ...根据 PyPDF 的检测结果可以发现它将 PDF 中的字符序列character sequences序列化为一个单一的长序列而不保留结构信息。换句话说它将文档中的每一行都视为由换行符\n 分隔的序列因此无法准确识别文本段落或表格。 这种限制是基于规则的 pdf 解析方法的固有特征。 2.2 基于深度学习模型的解析方法 这种方法的优点在于能够准确识别文档的整体布局包括表格和文本段落甚至可以理解表格的内部结构。说明这种方法可以将文档划分为定义明确、完整的信息单元同时还可以保留预期的含义和结构。 不过这种方法也存在一定的局限性。目标检测object detection和 OCR 阶段可能比较耗时。因此建议使用 GPU 或其他用于加速特定计算任务的硬件并采用多个进程和线程并行处理。 这种方法需要使用目标检测object detection技术和 OCR 模型我已经测试了几个最具代表性的开源框架 Unstructured[5]该框架已经被集成到 langchain[6] 中。在 infer_table_structure 为 True 的情况下hi_res 策略的表格识别效果很好。然而fast 策略由于没有使用目标检测模型错误地识别了许多图像和表格因此表现不佳。Layout-parser[7]如果需要识别结构复杂的 PDF建议使用框架中最大规模的模型这样准确率会更高不过速度可能会稍慢一些。此外Layout-parser 的模型[8]似乎在过去两年中没有更新过。PP-StructureV2[9] 采用了各种模型组合进行文档分析性能高于平均水平。其架构如图 4 所示 图 4作者提出的 PP-StructureV2 框架。它包含两个子系统布局信息提取layout information extraction和关键信息提取key information extraction。来源PP-StructureV2[9]。 除了前文提到的那些开源工具外还存在像 ChatDOC 这样需要付费才能使用的商业工具这些商业工具利用基于文档布局的识别和OCR光学字符识别方法来解析PDF文档。 接下来我们将详细说明如何使用开源的 unstructured[10] 框架来解析 PDF解决下面这三个关键挑战。 挑战 1如何从表格和图片中提取数据 在本小节我们将以 unstructured[10] 框架为例。检测到的表格数据可以直接导出为 HTML。相关代码如下 from unstructured.partition.pdf import partition_pdffilename /Users/Florian/Downloads/Attention_Is_All_You_Need.pdf# infer_table_structureTrue automatically selects hi_res strategy elements partition_pdf(filenamefilename, infer_table_structureTrue) tables [el for el in elements if el.category Table]print(tables[0].text) print(--------------------------------------------------) print(tables[0].metadata.text_as_html)通过跟踪 partition_pdf 函数的内部代码逻辑绘制了如图 5 的基本代码流程图。 图 5partition_pdf 函数的内部代码逻辑。Image by author。 代码运行的结果如下 Layer Type Self-Attention Recurrent Convolutional Self-Attention (restricted) Complexity per Layer O(n2 · d) O(n · d2) O(k · n · d2) O(r · n · d) Sequential Maximum Path Length Operations O(1) O(n) O(1) O(1) O(1) O(n) O(logk(n)) O(n/r) -------------------------------------------------- tabletheadthLayer Type/ththComplexity per Layer/ththSequential Operations/ththMaximum Path Length/th/theadtrtdSelf-Attention/tdtdO(n? - d)/tdtdO(1)/tdtdO(1)/td/trtrtdRecurrent/tdtdO(n- d?)/tdtdO(n)/tdtdO(n)/td/trtrtdConvolutional/tdtdO(k-n-d?)/tdtdO(1)/tdtdO(logy(n))/td/trtrtdSelf-Attention (restricted)/tdtdO(r-n-d)/tdtdol)/tdtdO(n/r)/td/tr/table复制 HTML 标签并将它们保存为 HTML 文件。然后使用 Chrome 打开它如图 6 所示 图 6图 3 中表格 1 的内容提取。Image by author。 可以看出unstructured 算法基本准确提取了整个表格的数据。 挑战 2如何重新排列检测到的数据块特别是如何处理双列double-column PDF 在处理双列double-column PDF 时我们以《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》[11]论文为例。红色箭头表示阅读顺序 图 7Double-column page 确定布局后unstructured 框架会将每个页面划分为若干矩形块如图 8 所示。 图 8布局检测结果的可视化。Image by author。 每个矩形块的详细信息可以按以下格式获取 [LayoutElement(bboxRectangle(x1851.1539916992188, y1181.15073777777613, x21467.844970703125, y2587.8204599999975), textThese approaches have been generalized to coarser granularities, such as sentence embed- dings (Kiros et al., 2015; Logeswaran and Lee, 2018) or paragraph embeddings (Le and Mikolov, 2014). To train sentence representations, prior work has used objectives to rank candidate next sentences (Jernite et al., 2017; Logeswaran and Lee, 2018), left-to-right generation of next sen- tence words given a representation of the previous sentence (Kiros et al., 2015), or denoising auto- encoder derived objectives (Hill et al., 2016). , sourceSource.YOLOX: yolox, typeText, prob0.9519357085227966, image_pathNone, parentNone), LayoutElement(bboxRectangle(x1196.5296173095703, y1181.1507377777777, x2815.468994140625, y2512.548237777777), textword based only on its context. Unlike left-to- right language model pre-training, the MLM ob- jective enables the representation to fuse the left and the right context, which allows us to pre- In addi- train a deep bidirectional Transformer. tion to the masked language model, we also use a “next sentence prediction” task that jointly pre- trains text-pair representations. The contributions of our paper are as follows: , sourceSource.YOLOX: yolox, typeText, prob0.9517233967781067, image_pathNone, parentNone), LayoutElement(bboxRectangle(x1200.22352600097656, y1539.1451822222216, x2825.0242919921875, y2870.542682222221), text• We demonstrate the importance of bidirectional pre-training for language representations. Un- like Radford et al. (2018), which uses unidirec- tional language models for pre-training, BERT uses masked language models to enable pre- trained deep bidirectional representations. This is also in contrast to Peters et al. (2018a), which uses a shallow concatenation of independently trained left-to-right and right-to-left LMs. , sourceSource.YOLOX: yolox, typeList-item, prob0.9414362907409668, image_pathNone, parentNone), LayoutElement(bboxRectangle(x1851.8727416992188, y1599.8257377777753, x21468.0499267578125, y21420.4982377777742), textELMo and its predecessor (Peters et al., 2017, 2018a) generalize traditional word embedding re- search along a different dimension. They extract context-sensitive features from a left-to-right and a right-to-left language model. The contextual rep- resentation of each token is the concatenation of the left-to-right and right-to-left representations. When integrating contextual word embeddings with existing task-specific architectures, ELMo advances the state of the art for several major NLP benchmarks (Peters et al., 2018a) including ques- tion answering (Rajpurkar et al., 2016), sentiment analysis (Socher et al., 2013), and named entity recognition (Tjong Kim Sang and De Meulder, 2003). Melamud et al. (2016) proposed learning contextual representations through a task to pre- dict a single word from both left and right context using LSTMs. Similar to ELMo, their model is feature-based and not deeply bidirectional. Fedus et al. (2018) shows that the cloze task can be used to improve the robustness of text generation mod- els. , sourceSource.YOLOX: yolox, typeText, prob0.938507616519928, image_pathNone, parentNone), LayoutElement(bboxRectangle(x1199.3734130859375, y1900.5257377777765, x2824.69873046875, y21156.648237777776), text• We show that pre-trained representations reduce the need for many heavily-engineered task- specific architectures. BERT is the first fine- tuning based representation model that achieves state-of-the-art performance on a large suite of sentence-level and token-level tasks, outper- forming many task-specific architectures. , sourceSource.YOLOX: yolox, typeList-item, prob0.9461237788200378, image_pathNone, parentNone), LayoutElement(bboxRectangle(x1195.5695343017578, y11185.526123046875, x2815.9393920898438, y21330.3272705078125), text• BERT advances the state of the art for eleven NLP tasks. The code and pre-trained mod- els are available at https://github.com/ google-research/bert. , sourceSource.YOLOX: yolox, typeList-item, prob0.9213815927505493, image_pathNone, parentNone), LayoutElement(bboxRectangle(x1195.33956909179688, y11360.7886962890625, x2447.47264000000007, y21397.038330078125), text2 Related Work , sourceSource.YOLOX: yolox, typeSection-header, prob0.8663332462310791, image_pathNone, parentNone), LayoutElement(bboxRectangle(x1197.7477264404297, y11419.3353271484375, x2817.3308715820312, y21527.54443359375), textThere is a long history of pre-training general lan- guage representations, and we briefly review the most widely-used approaches in this section. , sourceSource.YOLOX: yolox, typeText, prob0.928022563457489, image_pathNone, parentNone), LayoutElement(bboxRectangle(x1851.0028686523438, y11468.341394166663, x21420.4693603515625, y21498.6444497222187), text2.2 Unsupervised Fine-tuning Approaches , sourceSource.YOLOX: yolox, typeSection-header, prob0.8346447348594666, image_pathNone, parentNone), LayoutElement(bboxRectangle(x1853.5444444444446, y11526.3701822222185, x21470.989990234375, y21669.5843488888852), textAs with the feature-based approaches, the first works in this direction only pre-trained word em- (Col- bedding parameters from unlabeled text lobert and Weston, 2008). , sourceSource.YOLOX: yolox, typeText, prob0.9344717860221863, image_pathNone, parentNone), LayoutElement(bboxRectangle(x1200.00000000000009, y11556.2037353515625, x2799.1743774414062, y21588.031982421875), text2.1 Unsupervised Feature-based Approaches , sourceSource.YOLOX: yolox, typeSection-header, prob0.8317819237709045, image_pathNone, parentNone), LayoutElement(bboxRectangle(x1198.64227294921875, y11606.3146266666645, x2815.2886352539062, y22125.895459999998), textLearning widely applicable representations of words has been an active area of research for decades, including non-neural (Brown et al., 1992; Ando and Zhang, 2005; Blitzer et al., 2006) and neural (Mikolov et al., 2013; Pennington et al., 2014) methods. Pre-trained word embeddings are an integral part of modern NLP systems, of- fering significant improvements over embeddings learned from scratch (Turian et al., 2010). To pre- train word embedding vectors, left-to-right lan- guage modeling objectives have been used (Mnih and Hinton, 2009), as well as objectives to dis- criminate correct from incorrect words in left and right context (Mikolov et al., 2013). , sourceSource.YOLOX: yolox, typeText, prob0.9450697302818298, image_pathNone, parentNone), LayoutElement(bboxRectangle(x1853.4905395507812, y11681.5868488888855, x21467.8729248046875, y22125.8954599999965), textMore recently, sentence or document encoders which produce contextual token representations have been pre-trained from unlabeled text and fine-tuned for a supervised downstream task (Dai and Le, 2015; Howard and Ruder, 2018; Radford et al., 2018). The advantage of these approaches is that few parameters need to be learned from scratch. At least partly due to this advantage, OpenAI GPT (Radford et al., 2018) achieved pre- viously state-of-the-art results on many sentence- level tasks from the GLUE benchmark (Wang language model- Left-to-right et al., 2018a). , sourceSource.YOLOX: yolox, typeText, prob0.9476840496063232, image_pathNone, parentNone)]其中 (x1, y1) 是左上顶点的坐标而 (x2, y2) 是右下顶点的坐标 (x_1, y_1) --------|             ||             ||             |---------- (x_2, y_2)此时你可以选择重新调整reshape页面的阅读顺序。Unstructured 框架已经内置了排序算法但我发现在处理 double-column 的情况时排序结果并不令我满意。 因此有必要设计一种算法处理这种情况。最简单的方法是首先按照左上顶点的横坐标进行排序如果横坐标相同则按纵坐标进行排序。其伪代码如下 layout.sort(keylambda z: (z.bbox.x1, z.bbox.y1, z.bbox.x2, z.bbox.y2))不过我们发现即使是同一列中的图块其横坐标也可能存在变化。如图 9 所示紫线指向的 block 横坐标 bbox.x1 实际上更靠左。进行排序时它的位置会在绿线指向的 block 之前这显然违反了文档的阅读顺序。 图 9同一列的横坐标可能会有变化。Image by author。 在这种情况下一种具备可行性的算法如下 首先对所有左上顶点 x 坐标 x1 进行排序得到 x1_min然后对所有右下顶点 x 坐标 x2 进行排序得到 x2_max接下来确定页面中心线的 x 坐标为 x1_min min([el.bbox.x1 for el in layout]) x2_max max([el.bbox.x2 for el in layout]) mid_line_x_coordinate (x2_max x1_min) / 2之后如果 bbox.x1 mid_line_x_coordinate则将该 block 划为左列的一部分。否则将其视为右列的一部分。 分类完成后根据它们的 y 坐标对每列内的每个 block 进行排序。最后将右侧列连接到左侧列的右侧。 left_column [] right_column [] for el in layout:if el.bbox.x1 mid_line_x_coordinate:left_column.append(el)else:right_column.append(el)left_column.sort(key lambda z: z.bbox.y1) right_column.sort(key lambda z: z.bbox.y1) sorted_layout left_column right_column值得一提的是这一算法改进也能兼容单栏 PDF 的解析。 挑战 3如何提取多级标题 提取标题包括多级标题的目的是增强 LLM 所提供回复内容的准确性。 例如如果用户想了解图 9 中第 2.1 节的大意只需准确提取出第 2.1 节的标题并将其与相关内容一起作为上下文发送给 LLM最终所得到的回复内容的准确性就会大大提高。 该算法仍然依赖于图 9 所示的布局块layout blocks。我们可以提取 type’Section-header’ 的 block并计算高度差值bbox.y2 - bbox.y1。高度差值height difference最大的 block 对应一级标题其次是二级标题然后是三级标题。 2.3 基于多模态大模型解析 PDF 中的复杂结构 在多模态模型得到快速发展和广泛应用之后也可以利用多模态模型来解析表格。有几种选择[12] 检索相关图像PDF 页面并将它们发送到 GPT4-V 以响应用户向系统提交的问题或需求。将每个 PDF 页面视为一张图像让 GPT4-V 对每个页面进行图像推理。通过图像推理构建 Text Vector Store index 译者注应当是对文本向量进行索引和检索的数据结构或存储空间。使用 Image Reasoning Vectore Store 译者注应当为用于存储图像推理向量的数据库或仓库查询答案。使用 Table Transformer 从检索到的图像中裁剪表格信息然后将这些裁剪后的图像发送到 GPT4-V 以响应用户向系统提交的问题或需求。对裁剪后的表格图像使用 OCR 技术进行识别然后将数据发送到 GPT4 / GPT-3.5 以回答用户向系统提交的问题。 经过测试确定第三种方法最为有效。 此外我们还可以使用多模态模型从图像中提取或总结关键信息因为 PDF 文件可轻松转换为图像如图 10 所示。 图 10从图像中提取或总结关键信息。来源GPT-4 with Vision: Complete Guide and Evaluation[13] 03 Conclusion 一般几乎所有的非结构化文档都具有高度的灵活性需要各种各样的解析技术。然而业界目前还没有就使用哪种方法达成共识。 在这种情况下建议选择最适合项目需求的方法根据不同类型的 PDF 文件采取特定的处理方法。例如论文、书籍和财务报表等非结构性文档可能会根据其特点进行独特的布局设计。 尽管如此如果条件允许仍建议选择基于深度学习或多模态的方法。这些方法可以有效地将文档分割成定义明确、完整的信息单元从而最大限度地保留文档的原意和结构。 Thanks for reading! ———— Florian June An artificial intelligence researcher, mainly write articles about Large Language Models, data structures and algorithms, and NLP. END 参考资料 [1]https://github.com/py-pdf/pypdf [2]https://github.com/langchain-ai/langchain/blob/v0.1.1/libs/langchain/langchain/document_loaders/pdf.py [3]https://github.com/run-llama/llama_index/blob/v0.9.32/llama_index/readers/file/docs_reader.py [4]https://arxiv.org/pdf/1706.03762.pdf [5]http://unstructured-io.github.io/unstructured/ [6]https://github.com/langchain-ai/langchain/blob/master/libs/langchain/langchain/document_loaders/pdf.py [7]http://github.com/Layout-Parser/layout-parser [8]https://layout-parser.github.io/platform/ [9]https://arxiv.org/pdf/2210.05391.pdf [10]https://github.com/Unstructured-IO/unstructured [11]https://arxiv.org/pdf/1810.04805.pdf [12]https://docs.llamaindex.ai/en/stable/examples/multi_modal/multi_modal_pdf_tables.html [13]https://blog.roboflow.com/gpt-4-vision/ 本文经原作者授权由 Baihai IDP 编译。如需转载译文请联系获取授权。 原文链接 https://pub.towardsai.net/advanced-rag-02-unveiling-pdf-parsing-b84ae866344e
http://www.dnsts.com.cn/news/149189.html

相关文章:

  • 农业网站怎么做百度推广百度关键词工具入口
  • 自己做的个人网站无法备案unity3d转行网站开发
  • 烟台html5网站建设html中文网站模板下载
  • 风铃微网站怎么做联通套餐
  • 做阿里巴巴还是做网站好凤凰军事新闻最新消息
  • 做内部网站费用如何修改wordpress的字体
  • 网站地址怎么申请注册青岛建设工程管理信息网
  • 揭阳购物网站开发设计网络书城网站开发 需求分析
  • 快速搭建网站工具WordPress移动端加搜索
  • 专业做网站制作自助建站系统微信商城怎么进
  • 小企业做网站怎么做徐州h5建站模板
  • php网站制作 青岛动漫设计在哪里可以学
  • 微信公众平台视频网站开发晋江论坛兔区网友留言区
  • 黑龙江建设兵团知青网站南京明辉建设集团网站
  • 怎么建设个人网站 新手学做网站软件定制开发公司地址
  • 芸志建站怎么建立网站网站建设 海外房产
  • 网站地址地图怎么做工程房地产行业一条龙网站
  • 建设网站需要什么资质吗王也踏青
  • 建筑设计师网站网站建设是什么部门
  • 工厂网站建设公司自己做音乐网站
  • c2c网站怎么做贵州建设职业技术学院招商网站
  • 网站服务器ip地址怎么查dedecms生成xml网站地图
  • 企业网站上线成都哪家公司做网站最好
  • 网站建设设计原则装饰网站建设的背景
  • 南漳网站开发外贸公司做网站
  • 电子商务网站规划与建设试题1688跨境电商平台
  • 江门住房城乡建设厅网站黄石规划建设局网站
  • nodejs 网站开发模块网站建设背景图片大小的修改
  • 大兴安岭商城网站开发设计网站运营经理岗位要求
  • 购物网站开发网站建设策划书事物选题