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

导航网站制作基础建站如何提升和优化

导航网站制作,基础建站如何提升和优化,武汉商城网站制作,武汉做网站便宜公司哪家好目录 第一部分、前言 1、获取心知天气API接口 2、硬件准备 第二部分、电脑串口助手调试WIFI模块获取天气 1、ESP8266获取天气的流程 2、具体步骤 第三部分、STM32驱动ESP8266模块获取天气数据 1、天气数据的解析 1.1、什么函数来解析天气数据? 2.1、解析后…

目录

第一部分、前言

1、获取心知天气API接口

2、硬件准备

第二部分、电脑串口助手调试WIFI模块获取天气

1、ESP8266获取天气的流程

2、具体步骤

第三部分、STM32驱动ESP8266模块获取天气数据

1、天气数据的解析

1.1、什么函数来解析天气数据?

2.1、解析后的数据如何使用?

 2、相关代码

2.1、main.c文件

2.2、esp8266.c文件

第四部分、总结

1、效果展示

2、完整的工程

3、补充


第一部分、前言

        这篇博客拖了很久很久,本来是打算和前面一篇一起发出来的,但是那段时间因为一些事情耽搁了,这篇博客写了一半,剩下的一直都没有写,其次就是人也有点懒,也不太想动🤪🤪。

        这几天考试周来了,复习又不想复习,不如把这篇内容更新完整,这篇更新完之后,STM32专栏应该不会再更新了。

        然后,后面我打算出一期C语言的学习笔记专栏,再后面就是FPGA的学习笔记专栏。想是这么想的,不知道能不能做好,哈哈🤭。

1、获取心知天气API接口

        这里还是希望大家先去看我的第一篇博客:【STM32训练—WiFi模块】第一篇、STM32驱动ESP8266WiFi模块获取网络时间通过这篇博客你会明白WIFI模块获取网络流程是什么样子的,搞懂了这个,你会发现获取天气和获取时间的步骤完全一样,代码也没有什么大的变化。

        接着再来说一下心知天气,上一篇文章提到时间的接口是由苏宁后台提供的“quan.suning.com/getSysTime.do”,那么这里想获取天气,那么也需要一个API的接口,这里的API接口由心知天气给我们提供。

        因此需要注册一个心知天气,获取自己的密钥。关于注册的过程可以参考心知天气提供的文档:注册与登陆 | 心知天气文档 (seniverse.com)

        注册完成后,如何获取属于自己的API接口呢,参考文档如下:查看/修改你的API密钥 (yuque.com)

        这是我的API接口,点进去之后就会看到目前杭州的天气数据:https://api.seniverse.com/v3/weather/now.json?key=SwLQ3i0Q5TNa6NSKT&location=hangzhou&language=zh-Hans&unit=c

        点击上面的链接,就会获取到天气数据,接下来的步骤就和前面获取时间一样,主要区别就是将时间的API接口换成刚刚注册得到的心知天气的API接口即可是不是发现原来也就这么回事。

2、硬件准备

         STM32选用核心板F103C8T6,然后再加一个ESP8266 WiFi模块(任何型号应该都可以,我这次用的ESP-01s),最后需要一个USB-TTL模块用来打印串口数据。

        需要注意的是:我的这个ESP-01S,有一个EN使能端,必须要给高电平才能用,上一篇博客用的那个WIFI模块没有EN使能端。所以希望大家注意自己的模块。

第二部分、电脑串口助手调试WIFI模块获取天气

1、ESP8266获取天气的流程

        流程和获取时间的流程大致一样,只不过这里获取的为天气数据。

2、具体步骤

 第一步、AT指令集

0:AT
1:AT+RST
2:AT+CWMODE=1
3:AT+CIPMUX=0
4:AT+CWJAP="你的WiFi名称","你的WiFi密码"
5:AT+CIPMODE=1
6:AT+CIPSTART="TCP","api.seniverse.com",80
7:AT+CIPSEND
8:GET https://api.seniverse.com/v3/weather/now.json?key=SwLQ3i0Q5TNa6NSKT&location=hangzhou&language=en&unit=c
9:+++

        注意:所有串口步骤同前一篇文章,这里直接有区别的步骤为第八步,因此这里直接跳转到第八步

 第八步、连接目标的服务器,TCP是传输协议,api.seniverse.com是心知天气服务器的IP地址,80是服务器端口。

 第十步、第九步和前文一样,接着再发送获取数据的请求,得到天气数据

 第十一步、关于退出透传的方式也和前面博客完全一样,这里就不再展示,所以一定要看第一篇文章,那个文章介绍的太详细了。

第三部分、STM32驱动ESP8266模块获取天气数据

1、天气数据的解析

        这里天气的解析我调用了cJSON的库,你不用管这个库怎么写的,原理是啥,知道它是怎么用的就可以了,例如调用什么函数来解析天气数据?解析后的数据如何使用?弄明白这两个问题,就够了。

        1.1、什么函数来解析天气数据?

        时间太久了,我都不知道我哪里弄来的这个函数,反正挺好用的,侵权联系我删除!

        这个函数我放在我工程的"cJSON.c"文件最下面。

/*********************************************************************************
* Function Name    : cJSON_WeatherParse,解析天气数据
* Parameter		   : JSON:天气数据包  results:保存解析后得到的有用的数据
* Return Value     : 0:成功 其他:错误
* Function Explain : 
* Create Date      : 2017.12.6 by lzn
**********************************************************************************/
int cJSON_WeatherParse(char *JSON, Results *results)
{cJSON *json,*arrayItem,*object,*subobject,*item;json = cJSON_Parse(JSON); //解析JSON数据包if(json == NULL)		  //检测JSON数据包是否存在语法上的错误,返回NULL表示数据包无效{printf("Error before: [%s] \r\n",cJSON_GetErrorPtr()); //打印数据包语法错误的位置return 1;}else{if((arrayItem = cJSON_GetObjectItem(json,"results")) != NULL); //匹配字符串"results",获取数组内容{int size = cJSON_GetArraySize(arrayItem);     //获取数组中对象个数printf("cJSON_GetArraySize: size=%d \r\n",size); if((object = cJSON_GetArrayItem(arrayItem,0)) != NULL)//获取父对象内容{/* 匹配子对象1 */if((subobject = cJSON_GetObjectItem(object,"location")) != NULL){printf("---------------------------------subobject1-------------------------------\r\n");if((item = cJSON_GetObjectItem(subobject,"id")) != NULL)   //匹配子对象1成员"id"{printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);memcpy(results[0].location.id,item->valuestring,strlen(item->valuestring));}if((item = cJSON_GetObjectItem(subobject,"name")) != NULL) //匹配子对象1成员"name"{printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);memcpy(results[0].location.name,item->valuestring,strlen(item->valuestring));}if((item = cJSON_GetObjectItem(subobject,"country")) != NULL)//匹配子对象1成员"country"{printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);memcpy(results[0].location.country,item->valuestring,strlen(item->valuestring));}if((item = cJSON_GetObjectItem(subobject,"path")) != NULL)  //匹配子对象1成员"path"{printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);memcpy(results[0].location.path,item->valuestring,strlen(item->valuestring));}if((item = cJSON_GetObjectItem(subobject,"timezone")) != NULL)//匹配子对象1成员"timezone"{printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);memcpy(results[0].location.timezone,item->valuestring,strlen(item->valuestring));}if((item = cJSON_GetObjectItem(subobject,"timezone_offset")) != NULL)//匹配子对象1成员"timezone_offset"{printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);memcpy(results[0].location.timezone_offset,item->valuestring,strlen(item->valuestring));}}/* 匹配子对象2 */if((subobject = cJSON_GetObjectItem(object,"now")) != NULL){printf("---------------------------------subobject2-------------------------------\r\n");if((item = cJSON_GetObjectItem(subobject,"text")) != NULL)//匹配子对象2成员"text"{printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);memcpy(results[0].now.text,item->valuestring,strlen(item->valuestring));}if((item = cJSON_GetObjectItem(subobject,"code")) != NULL)//匹配子对象2成员"code"{printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);memcpy(results[0].now.code,item->valuestring,strlen(item->valuestring));}if((item = cJSON_GetObjectItem(subobject,"temperature")) != NULL) //匹配子对象2成员"temperature"{printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);memcpy(results[0].now.temperature,item->valuestring,strlen(item->valuestring));}}/* 匹配子对象3 */if((subobject = cJSON_GetObjectItem(object,"last_update")) != NULL){printf("---------------------------------subobject3-------------------------------\r\n");printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",subobject->type,subobject->string,subobject->valuestring);memcpy(results[0].last_update,item->valuestring,strlen(subobject->valuestring));}} }}cJSON_Delete(json); //释放cJSON_Parse()分配出来的内存空间return 0;
}

        2.1、解析后的数据如何使用?

        调用上面那个函数后,解析的数据存放在一个双层结构体当中,因此只需访问结构体的成员就可以,每个成员的名称与心知天气返回的名称相匹配。

        具体的信息参考心知天气的文档:极速实况 (yuque.com)

 2、相关代码

        2.1、main.c文件

#include "sys.h"
#include "led.h"
#include "delay.h"
#include "usart.h"
#include "esp8266.h"
#include "cJSON.h" //解析天气//天气数据
extern unsigned char Weather_buff[300];
//天气解析
Results Weather_results[] = {{0}};int main()
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//中断控制器分组设置Usart1_Init(115200);Usart2_Init(115200);LED_Init();delay_init();//初始化很重要//用不了的函数一般都是没有初始化ESP8266_Init();Get_current_weather();//获取天气while(1){LED0 = 0;delay_ms(500);delay_ms(500);delay_ms(500);delay_ms(500);LED0 = 1;delay_ms(500);delay_ms(500);delay_ms(500);delay_ms(500);cJSON_WeatherParse((char *)Weather_buff, Weather_results);printf("%s",Weather_buff);	//打印结构体内内容printf("\r\n 打印结构体内内容如下: \r\n");printf("%s \r\n",Weather_results[0].now.text);printf("%s \r\n",Weather_results[0].now.temperature);printf("%s \r\n",Weather_results[0].location.path);printf("%s \r\n",Weather_results[0].location.country);}}

        2.2、esp8266.c文件

#include "stm32f10x.h"
#include "sys.h"
#include "string.h"
#include "stdlib.h"
#include "esp8266.h"#include "usart.h"
#include "delay.h"
#include "led.h"//WIFI和密码·
#define ESP8266_WIFI_INFO		"AT+CWJAP=\"iPhone111\",\"123456789\"\r\n"
//心知天气的API
#define Weather_TCP		"AT+CIPSTART=\"TCP\",\"api.seniverse.com\",80\r\n"
//心知天气GET报文
/*这里城市  恩施    语言为  英文*/
#define Weather_GET		"GET https://api.seniverse.com/v3/weather/now.json?key=SwLQ3i0Q5TNa6NSKT&location=enshi&language=en&unit=c\r\n"//ESP8266数据存放
unsigned char esp8266_buf[300] = {0};
unsigned short esp8266_cnt = 0, esp8266_cntPre = 0;
//存放天气数据
unsigned char Weather_buff[300];   //位数是随机确定的/**************************************************************************/
//函数作用:ESP8266_Init初始化函数
//函数名称:ESP8266_Init(void);
//内部参数:
//修改日期:2022年4月18日  下午16:18
//作者:    大屁桃
/**************************************************************************/
void ESP8266_Init(void)
{ESP8266_Clear();/*让WIFI推出透传模式*/while(ESP8266_SendCmd("+++", ""))  delay_ms(500);UsartPrintf(USART_DEBUG, "1.AT\r\n");while(ESP8266_SendCmd("AT\r\n", "OK"))delay_ms(500);////加一步ESP8266复位操作UsartPrintf(USART_DEBUG, "2.RST\r\n");ESP8266_SendCmd("AT+RST\r\n", "");delay_ms(500);ESP8266_SendCmd("AT+CIPCLOSE\r\n", "");delay_ms(500);/UsartPrintf(USART_DEBUG, "3.CWMODE\r\n");while(ESP8266_SendCmd("AT+CWMODE=1\r\n", "OK"))delay_ms(500);UsartPrintf(USART_DEBUG, "4.AT+CIPMUX\r\n");while(ESP8266_SendCmd("AT+CIPMUX=0\r\n", "OK"))delay_ms(500);UsartPrintf(USART_DEBUG, "5.CWJAP\r\n");while(ESP8266_SendCmd(ESP8266_WIFI_INFO, "WIFI GOT IP"))delay_ms(500);delay_ms(500);delay_ms(500);UsartPrintf(USART_DEBUG, "ESP8266_Init OK\r\n");
}/*获取网络天气数据*/
/**************************************************************************/
//函数作用:获取心知天气函数
//函数名称:Get_current_weather(void);
//内部参数:
//修改日期:2022年4月18日  下午16:18
//作者:    大屁桃
/**************************************************************************/
void Get_current_weather(void)
{ESP8266_Clear();UsartPrintf(USART_DEBUG, "6.Weather_TCP OK\r\n");	while(ESP8266_SendCmd(Weather_TCP, "CONNECT"))delay_ms(500);delay_ms(500);UsartPrintf(USART_DEBUG, "7.AT+CIPMODE=1 OK\r\n");		while(ESP8266_SendCmd("AT+CIPMODE=1\r\n", "OK"))delay_ms(500);delay_ms(500);delay_ms(500);
/*sizeof(Weather_GET),必须用sizeof函数,用strlen没有用*/  	ESP8266_SendData((u8 *)Weather_GET, sizeof(Weather_GET)); //发送AT+CIPSEND  以及 Weather_GETESP8266_GetIPD_GET(200,Weather_buff);ESP8266_Clear();//清除缓存数据	delay_ms(500);delay_ms(500);while(ESP8266_SendCmd("+++", ""))      /*退出透传模式*/delay_ms(500);UsartPrintf(USART_DEBUG, "+++ OK\r\n");	while(ESP8266_SendCmd("AT\r\n", "OK"))   //验证是否退出透传模式delay_ms(500);UsartPrintf(USART_DEBUG, "1.AT\r\n");
}/**************************************************************************/
//函数作用:串口二中断函数
//函数名称:USART2_IRQHandler();
//内部参数:
//修改日期:2022年4月18日  下午4:18
//作者:    大屁桃
/**************************************************************************/
void USART2_IRQHandler(void)
{if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中断{if(esp8266_cnt >= sizeof(esp8266_buf))	esp8266_cnt = 0; //防止串口被刷爆				esp8266_buf[esp8266_cnt++] = USART2->DR;  //		USART_SendData(USART1,USART2->DR);      //让接收到的数据打印在串口一上USART_ClearFlag(USART2, USART_FLAG_RXNE);}
}//==========================================================
//	函数名称:	ESP8266_Clear
//
//	函数功能:	清空缓存
//
//	入口参数:	无
//
//	返回参数:	无
//
//	说明:		
//==========================================================
void ESP8266_Clear(void)
{memset(esp8266_buf, 0, sizeof(esp8266_buf));esp8266_cnt = 0;}
//==========================================================
//	函数名称:	ESP8266_WaitRecive
//
//	函数功能:	等待接收完成
//
//	入口参数:	无
//
//	返回参数:	REV_OK-接收完成		REV_WAIT-接收超时未完成
//
//	说明:		循环调用检测是否接收完成
//==========================================================
_Bool ESP8266_WaitRecive(void)
{if(esp8266_cnt == 0) 							//如果接收计数为0 则说明没有处于接收数据中,所以直接跳出,结束函数return REV_WAIT;if(esp8266_cnt == esp8266_cntPre)				//如果上一次的值和这次相同,则说明接收完毕{esp8266_cnt = 0;							//清0接收计数return REV_OK;								//返回接收完成标志}esp8266_cntPre = esp8266_cnt;					//置为相同return REV_WAIT;								//返回接收未完成标志}//==========================================================
//	函数名称:	ESP8266_GetIPD
//
//	函数功能:	copy天气数据到Weather_buff数组里面
//
//	返回参数:	平台返回的原始数据
//
//	说明:		copy天气数据到Weather_buff
//==========================================================unsigned char *ESP8266_GetIPD_GET(unsigned short timeOut,u8 *buff)//这里我用了一个全局变量将esp8266buf储存到这个全局变量里面
{do{delay_ms(5);													} while(timeOut--);strcpy((char*)buff,(char*)esp8266_buf);return buff;														
}/*还未用到*/
//==========================================================
//	函数名称:	ESP8266_GetIPD
//
//	函数功能:	获取平台返回的数据
//
//	入口参数:	等待的时间(乘以10ms)
//
//	返回参数:	平台返回的原始数据
//
//	说明:		不同网络设备返回的格式不同,需要去调试
//				如ESP8266的返回格式为	"+IPD,x:yyy"	x代表数据长度,yyy是数据内容
//==========================================================
unsigned char *ESP8266_GetIPD(unsigned short timeOut)
{char *ptrIPD = NULL;do{if(ESP8266_WaitRecive() == REV_OK)								//如果接收完成{ptrIPD = strstr((char *)esp8266_buf, "IPD,");				//搜索“IPD”头if(ptrIPD == NULL)											//如果没找到,可能是IPD头的延迟,还是需要等待一会,但不会超过设定的时间{//UsartPrintf(USART_DEBUG, "\"IPD\" not found\r\n");}else{ptrIPD = strchr(ptrIPD, ':');							//找到':'if(ptrIPD != NULL){ptrIPD++;return (unsigned char *)(ptrIPD);}elsereturn NULL;}}delay_ms(5);													//延时等待} while(timeOut--);return NULL;														//超时还未找到,返回空指针}
//==========================================================
//	函数名称:	ESP8266_SendCmd
//
//	函数功能:	发送命令
//
//	入口参数:	cmd:命令
//				res:需要检查的返回指令
//
//	返回参数:	0-成功	1-失败
//
//	说明:		
//==========================================================
_Bool ESP8266_SendCmd(char *cmd, char *res)
{unsigned char timeOut = 250;Usart_SendString(USART2, (unsigned char *)cmd, strlen((const char *)cmd));while(timeOut--){if(ESP8266_WaitRecive() == REV_OK)							//如果收到数据{		if(strstr((const char *)esp8266_buf, res) != NULL)		//如果检索到关键词{ESP8266_Clear();									//清空缓存return 0;}}delay_ms(10);}return 1;}//==========================================================
//	函数名称:	ESP8266_SendData
//
//	函数功能:	发送数据
//
//	入口参数:	data:数据
//				len:长度
//
//	返回参数:	无
//
//	说明:		
//==========================================================
void ESP8266_SendData(unsigned char *data, unsigned short len)
{char cmdBuf[32];ESP8266_Clear();								//清空接收缓存sprintf(cmdBuf, "AT+CIPSEND\r\n");		//发送命令if(!ESP8266_SendCmd(cmdBuf, ">"))				//收到‘>’时可以发送数据{UsartPrintf(USART_DEBUG, "8.AT+CIPSEND\r\n");/*发送请求数据*/Usart_SendString(USART2, data, len);		//发送设备连接请求数据		}
}

第四部分、总结

1、效果展示

        这是连接单片机后,单片机通过串口返回的数据,这里串口只展示了当前天气、当前温度,所在地区和所在国家的数据,若想增加在主程序中增加即可。

        单片机通过串口返回的数据和网址上显示的一致。

 2、完整的工程

        完整的工程代码点击该链接下载,无需积分,直接下载:STM32工程文件​​​​​​​

3、补充

        这篇博客说明了天气的获取方式,天气的读取,后面想做天气显示等应用,只需要加上LCD的驱动程序即可,花里胡哨的功能要靠自己去琢磨噻。

        最后希望博客对你有帮助,喜欢的话可以点个赞呢👍👍👍。


文章转载自:
http://clavicular.jtrb.cn
http://plc.jtrb.cn
http://miogeosynclinal.jtrb.cn
http://birdie.jtrb.cn
http://frugivore.jtrb.cn
http://partialize.jtrb.cn
http://heliotherapy.jtrb.cn
http://scrapheap.jtrb.cn
http://chicken.jtrb.cn
http://evita.jtrb.cn
http://mammonist.jtrb.cn
http://invenit.jtrb.cn
http://porism.jtrb.cn
http://serran.jtrb.cn
http://opaque.jtrb.cn
http://suntanned.jtrb.cn
http://pediculosis.jtrb.cn
http://heuchera.jtrb.cn
http://crucifix.jtrb.cn
http://osmoregulatory.jtrb.cn
http://recipient.jtrb.cn
http://kharakteristika.jtrb.cn
http://dart.jtrb.cn
http://destiny.jtrb.cn
http://logotherapy.jtrb.cn
http://domestication.jtrb.cn
http://zurich.jtrb.cn
http://gormandize.jtrb.cn
http://kilderkin.jtrb.cn
http://urushiol.jtrb.cn
http://horseplay.jtrb.cn
http://erudite.jtrb.cn
http://discovery.jtrb.cn
http://node.jtrb.cn
http://caterwaul.jtrb.cn
http://immunocytochemistry.jtrb.cn
http://asianic.jtrb.cn
http://ifc.jtrb.cn
http://spoonbeak.jtrb.cn
http://chiromancer.jtrb.cn
http://violone.jtrb.cn
http://absurdly.jtrb.cn
http://helene.jtrb.cn
http://reticulated.jtrb.cn
http://probate.jtrb.cn
http://papular.jtrb.cn
http://sining.jtrb.cn
http://grumblingly.jtrb.cn
http://peephole.jtrb.cn
http://anaesthetist.jtrb.cn
http://cinquefoil.jtrb.cn
http://sweepup.jtrb.cn
http://eustacy.jtrb.cn
http://coleoptile.jtrb.cn
http://pipless.jtrb.cn
http://acousticon.jtrb.cn
http://charity.jtrb.cn
http://hedjaz.jtrb.cn
http://monolog.jtrb.cn
http://epicotyledonary.jtrb.cn
http://chaplet.jtrb.cn
http://overaggressive.jtrb.cn
http://aganippe.jtrb.cn
http://musicality.jtrb.cn
http://callipee.jtrb.cn
http://unhip.jtrb.cn
http://cephalometer.jtrb.cn
http://rucus.jtrb.cn
http://unapproachable.jtrb.cn
http://mudfish.jtrb.cn
http://insufferably.jtrb.cn
http://tasteless.jtrb.cn
http://methodistic.jtrb.cn
http://rijsttafel.jtrb.cn
http://swear.jtrb.cn
http://navvy.jtrb.cn
http://lassa.jtrb.cn
http://colorized.jtrb.cn
http://emarcid.jtrb.cn
http://stewpot.jtrb.cn
http://engarb.jtrb.cn
http://gila.jtrb.cn
http://subarea.jtrb.cn
http://clairvoyant.jtrb.cn
http://dorhawk.jtrb.cn
http://privateersman.jtrb.cn
http://stamina.jtrb.cn
http://clothesbag.jtrb.cn
http://comeback.jtrb.cn
http://alible.jtrb.cn
http://sapsago.jtrb.cn
http://undelighting.jtrb.cn
http://possession.jtrb.cn
http://maundy.jtrb.cn
http://perpetuity.jtrb.cn
http://sanctification.jtrb.cn
http://esophagoscope.jtrb.cn
http://diesis.jtrb.cn
http://theropod.jtrb.cn
http://assuringly.jtrb.cn
http://www.15wanjia.com/news/58927.html

相关文章:

  • asp.net网站不能上传图片免费推广网站排行榜
  • 华立学院网站建设规划书的制作保温杯软文营销300字
  • 企业微信网站怎么做seo实战培训课程
  • 做网站怎么报价武汉整站优化
  • 自己买服务器建网站网络优化网站
  • discuz模板开发教程网站快速排名优化报价
  • 济宁苍南网站建设50个市场营销经典案例
  • 住房和城乡建设局网站2023年8月疫情爆发
  • 有没有专业做盐的网站星巴克seo网络推广
  • 主机屋怎么做网站今日头条新闻大事件
  • 营销型网站建设广告语家庭优化大师免费下载
  • 网站顶级导航制作方法合肥网站排名
  • 提高网站目标流量网络代运营推广
  • java电商网站开发技术点网站建设与管理
  • 动态网站开发总结感想网络营销专业好就业吗
  • 网站建设需要哪些知识怎么做一个公司网站
  • 宜春网站设计公司关键词怎么找出来
  • 儿童编程网课平台哪个好长春seo外包
  • 国外可以做非法网站吗crm软件
  • 多个网站优化怎么做刚刚地震最新消息今天
  • 网站设计要考虑的因素seo咨询价格找推推蛙
  • 衙门口网站建设咸阳网站建设公司
  • 2o17甘孜建设网站百度商家平台客服电话
  • 宁波网站推广优化外包公司打开网址资料网站
  • 自助网站免费注册曼联官方发文
  • 网站的目标优化seo是什么
  • 用php做视频网站的步骤关键词优化排名软件怎么样
  • 苏州吴江太湖新城建设局网站百度电脑版网页
  • 新手做的网站google chrome官网入口
  • cnzz统计代码放在后台网站为什么没显示网络软文发布