如果您想了解使用jsoup爬取数据实现android课程表的相关知识,那么本文是一篇不可错过的文章,我们将对python爬取课表进行全面详尽的解释,并且为您提供关于androidJsoup获取网站内容
如果您想了解使用jsoup爬取数据实现android课程表的相关知识,那么本文是一篇不可错过的文章,我们将对python爬取课表进行全面详尽的解释,并且为您提供关于android Jsoup获取网站内容 android获取新闻标题实例、android studio实现小吃商城,android课程设设计、android – 使用jsoup从网站网址中提取youtube视频网址、android – 使用JSoup获取表行的有价值的信息。
本文目录一览:- 使用jsoup爬取数据实现android课程表(python爬取课表)
- android Jsoup获取网站内容 android获取新闻标题实例
- android studio实现小吃商城,android课程设设计
- android – 使用jsoup从网站网址中提取youtube视频网址
- android – 使用JSoup获取表行
使用jsoup爬取数据实现android课程表(python爬取课表)
- 说明:只是爬虫的一个实现案例,所以没有多做功能,只做了登录跟课表功能,课表有修改周次,单击课程显示课程详细信息等功能。
- 开发平台:Android Studio
界面
使用TimetableView android课程表控件,需要添加依赖 jsoup依赖:compile ''org.jsoup:jsoup:1.10.2''
界面控件依赖: compile ''com.zhuangfei:TimetableView:2.0.6''
界面效果如下:
实现原理(爬虫实现)
使用jsoup爬取教务系统数据,connect()方法连接教务系统,直接利用cookie连接学生课表页面,解析返回的HTML页面获取该用户的全部课程并封装为java对象,再存入数据库,可以使用java后台服务器传json数据给android客户端,android客户端解析json数据,然后将课表数据展示出来。由于本案例小而单一,因此没有配置服务器,改为将爬取的数据直接存入到android本地数据库SQLite,课表的展示去本地数据库查询即可。 (注:各个学校学院的教务系统不尽相同,具体如何爬取数据详见jsoup官方网站jsoup)
实体类:
public class MySubject implements ScheduleEnable {
public static final String EXTRAS_ID="extras_id";
public static final String EXTRAS_NUMBER="extras_number";//小班号
public static final String EXTRAS_AD_URL="extras_ad_url";//广告Url
private int id;
/*
* 班号
* */
private String number;
/**
* 课程名
*/
private String name;
//无用数据
private String time;
/**
* 教室
*/
private String room;
/**
* 教师
*/
private String teacher;
/**
* 第几周至第几周上
*/
private List<Integer> weekList;
/**
* 开始上课的节次
*/
private int start;
/**
* 上课节数
*/
private int step;
/**
* 周几上
*/
private int day;
private String term;
/**
* 一个随机数,用于对应课程的颜色
*/
private int colorRandom = 0;
private String url;
public void setUrl(String url) {
this.url = url;
}
public String getUrl() {
return url;
}
public MySubject() {
// TODO Auto-generated constructor stub
}
public void setTime(String time) {
this.time = time;
}
public String getTime() {
return time;
}
public void setTerm(String term) {
this.term = term;
}
public String getTerm() {
return term;
}
public MySubject(String term,String name, String room, String teacher, List<Integer> weekList, int start, int step, int day, int colorRandom,String time,String number) {
super();
this.term=term;
this.name = name;
this.room = room;
this.teacher = teacher;
this.weekList=weekList;
this.start = start;
this.step = step;
this.day = day;
this.colorRandom = colorRandom;
this.time = time;
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRoom() {
return room;
}
public void setRoom(String room) {
this.room = room;
}
public String getTeacher() {
return teacher;
}
public void setTeacher(String teacher) {
this.teacher = teacher;
}
public void setWeekList(List<Integer> weekList) {
this.weekList = weekList;
}
public List<Integer> getWeekList() {
return weekList;
}
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getStep() {
return step;
}
public void setStep(int step) {
this.step = step;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public int getColorRandom() {
return colorRandom;
}
public void setColorRandom(int colorRandom) {
this.colorRandom = colorRandom;
}
@Override
public Schedule getSchedule() {
Schedule schedule=new Schedule();
schedule.setDay(getDay());
schedule.setName(getName());
schedule.setRoom(getRoom());
schedule.setStart(getStart());
schedule.setStep(getStep());
schedule.setTeacher(getTeacher());
schedule.setWeekList(getWeekList());
schedule.setColorRandom(2);
schedule.putExtras(EXTRAS_ID,getId());
schedule.putExtras(EXTRAS_AD_URL,getUrl());
schedule.putExtras(EXTRAS_NUMBER,getNumber());
return schedule;
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
课表界面,对依赖的课表控件进行了部分修改 数据源改为本地数据库查询,实现了动态获取数据源:mySubjects = getLocalSubjectData();
课表界面:
/**
* 课表Activity
*
*/
public class BaseFuncActivity extends AppCompatActivity implements View.OnClickListener{
private static final String TAG = "BaseFuncActivity";
//控件
TimetableView mTimetableView;
WeekView mWeekView;
Button moreButton;
LinearLayout layout;
TextView titleTextView;
List<MySubject> mySubjects;
//记录切换的周次,不一定是当前周
int target = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_func);
moreButton = (Button) findViewById(R.id.id_more);
moreButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showPopmenu();
}
});
//数据源
// mySubjects = SubjectRepertory.loadDefaultSubjects2();
//获取本地数据库数据
mySubjects = getLocalSubjectData();
//mySubjects.addAll(SubjectRepertory.loadDefaultSubjects());
titleTextView = (TextView) findViewById(R.id.id_title);
layout = (LinearLayout) findViewById(R.id.id_layout);
layout.setOnClickListener(this);
initTimetableView();//初始化
setMonthWidth();//设置月份宽度
// showTime();//显示时间
buildItemText();//设置课程文本内容
}
//获取本地数据库数据
private List<MySubject> getLocalSubjectData() {
List<MySubject> data = DaoImpl.GetCourceData();
if(!GetSaveStatus()){//非登录状态
DaoImpl.ClearCource();//清空表格
}
return data;
}
//判断登录状态
private boolean GetSaveStatus() {
SharedPreferences Preferences=getSharedPreferences("userInfo",MODE_PRIVATE);
String username=Preferences.getString("username","");
String password=Preferences.getString("password","");
if(username.equals("")&&password.equals("")){
return false;
}else{
return true;
}
}
/**
* 初始化课程控件
*/
private void initTimetableView() {
//获取控件
mWeekView = (WeekView) findViewById(R.id.id_weekview);
mTimetableView = (TimetableView) findViewById(R.id.id_timetableView);
//设置周次选择属性
mWeekView.source(mySubjects)
.curWeek(getLocalWeek())
.callback(new IWeekView.OnWeekItemClickedListener() {
@Override
public void onWeekClicked(int week) {
int cur = mTimetableView.curWeek();
//更新切换后的日期,从当前周cur->切换的周week
mTimetableView.onDateBuildListener()
.onUpdateDate(cur, week);
mTimetableView.changeWeekOnly(week);
}
})
.callback(new IWeekView.OnWeekLeftClickedListener() {
@Override
public void onWeekLeftClicked() {
onWeekLeftLayoutClicked();
}
})
.isShow(false)//设置隐藏,默认显示
.showView();
mTimetableView.source(mySubjects)
.curWeek(getLocalWeek())
.curTerm("")
.maxSlideItem(16)
.monthWidthDp(30)
//透明度
//日期栏0.1f、侧边栏0.1f,周次选择栏0.6f
//透明度范围为0->1,0为全透明,1为不透明
// .alpha(0.1f, 0.1f, 0.6f)
.callback(new ISchedule.OnItemClickListener() {
@Override
public void onItemClick(View v, List<Schedule> scheduleList) {
display(scheduleList);
}
})
.callback(new ISchedule.OnItemLongClickListener() {
@Override
public void onLongClick(View v, int day, int start) {
Toast.makeText(BaseFuncActivity.this,
"长按:周" + day + ",第" + start + "节",
Toast.LENGTH_SHORT).show();
}
})
.callback(new ISchedule.OnWeekChangedListener() {
@Override
public void onWeekChanged(int curWeek) {
titleTextView.setText("第" + curWeek + "周");
}
})
//旗标布局点击监听
.callback(new ISchedule.OnFlaglayoutClickListener() {
@Override
public void onFlaglayoutClick(int day, int start) {
mTimetableView.hideFlaglayout();
Toast.makeText(BaseFuncActivity.this,
"点击了旗标:周" + (day + 1) + ",第" + start + "节",
Toast.LENGTH_SHORT).show();
}
})
.showView();
}
/*
获取周数
* */
private int getLocalWeek() {
int weekResult = -1;
SharedPreferences preferences=getSharedPreferences("userInfo",MODE_PRIVATE);
int startWeek = preferences.getInt("weekNumber",-1);//,起始周从SharedPreferences获取
//华软教务系统总共17周
if(startWeek<=17){
String startDay=preferences.getString("date","");//起始周的星期一,从SharedPreferences获取,为yyyy-MM-dd格式
// String endDay= CalendarUtil.getMondayOfWeek();//当前周的星期一,为yyyy-MM-dd格式
String endDay= CalendarUtil.getMondayOfWeek2();//当前周的星期一,为yyyy-MM-dd格式
SharedPreferences.Editor editor=getSharedPreferences("userInfo",MODE_PRIVATE).edit();
editor.putString("current", endDay);
editor.commit();
int tempweek=CalendarUtil.getTwoDay(endDay,startDay);//间隔天数
int week=tempweek/7;
if(week==0){
weekResult=startWeek;
}else{
int finalweek=startWeek+week;
if(finalweek>17){
weekResult=17;
}else{
weekResult=finalweek;
}
}
return weekResult;
}else{
weekResult=17;
return weekResult;
}
}
/**
* 周次选择布局的左侧被点击时回调<br/>
* 对话框修改当前周次
*/
protected void onWeekLeftLayoutClicked() {
final String items[] = new String[20];
int itemCount = mWeekView.itemCount();
for (int i = 0; i < itemCount; i++) {
items[i] = "第" + (i + 1) + "周";
}
target = -1;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("设置当前周");
builder.setSingleChoiceItems(items, mTimetableView.curWeek() - 1,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
target = i;
}
});
builder.setPositiveButton("设置为当前周", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (target != -1) {
mWeekView.curWeek(target + 1).updateView();
mTimetableView.changeWeekForce(target + 1);
//把修改的周次存入SharedPreferences中
SharedPreferences.Editor editor=getSharedPreferences("userInfo",MODE_PRIVATE).edit();
editor.putInt("weekNumber",target+1);
// editor.putString("date", CalendarUtil.getMondayOfWeek());
editor.putString("date", CalendarUtil.getMondayOfWeek2());
editor.commit();
// Log.d("info",Integer.toString(target+1));
}
}
});
builder.setNegativeButton("取消", null);
builder.create().show();
}
/**
* 显示内容
*
* @param beans
*/
protected void display(List<Schedule> beans) {
String str = "";
for (Schedule bean : beans) {
str += bean.getName() + ","+bean.getWeekList().toString()+","+bean.getTeacher()+",["+bean.getExtras().get(MySubject.EXTRAS_NUMBER)+"]\n";
}
Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
}
/**
* 显示弹出菜单
*/
private void showPopmenu() {
PopupMenu popup = new PopupMenu(this, moreButton);
popup.getMenuInflater().inflate(R.menu.popmenu_base_func, popup.getMenu());
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
/*case R.id.top1:
addSubject();
break;
case R.id.top2:
deleteSubject();
break;*/
case R.id.top4:
hideNonThisWeek();
break;
case R.id.top5:
showNonThisWeek();
break;
/*case R.id.top6:
setMaxItem(8);
break;
case R.id.top7:
setMaxItem(10);
break;
case R.id.top8:
setMaxItem(12);
break;*/
case R.id.top9:
showTime();
break;
case R.id.top10:
hideTime();
break;
case R.id.top11:
showWeekView();
break;
case R.id.top12:
hideWeekView();
break;
/*case R.id.top13:
setMonthWidth();
break;
case R.id.top16:
resetMonthWidth();
break;*/
case R.id.top14:
hideWeekends();
break;
case R.id.top15:
showWeekends();
break;
case R.id.top17:
exitCurrentAccount();
break;
default:
break;
}
return true;
}
});
popup.show();
}
/**
* 退出当前账号
* 清空本地账号及SharedPreferences
*/
private void exitCurrentAccount() {
//清空数据库
DaoImpl.ClearCource();
//清空SharedPreferences
SharedPreferences.Editor editor=getSharedPreferences("userInfo",MODE_PRIVATE).edit();
editor.putInt("weekNumber",-1);
editor.putString("date", "");
editor.putString("username","");
editor.putString("password","");
editor.putString("current", "");
editor.commit();
Intent intent=new Intent(BaseFuncActivity.this,MainActivity.class);
startActivity(intent);
finish();
}
/**
* 删除课程
* 内部使用集合维护课程数据,操作集合的方法来操作它即可
* 最后更新一下视图(全局更新)
*/
protected void deleteSubject() {
int size = mTimetableView.dataSource().size();
int pos = (int) (Math.random() * size);
if (size > 0) {
mTimetableView.dataSource().remove(pos);
mTimetableView.updateView();
}
}
/**
* 添加课程
* 内部使用集合维护课程数据,操作集合的方法来操作它即可
* 最后更新一下视图(全局更新)
*/
protected void addSubject() {
List<Schedule> dataSource = mTimetableView.dataSource();
int size = dataSource.size();
if (size > 0) {
Schedule schedule = dataSource.get(0);
dataSource.add(schedule);
mTimetableView.updateView();
}
}
/**
* 隐藏非本周课程
* 修改了内容的显示,所以必须更新全部(性能不高)
* 建议:在初始化时设置该属性
* <p>
* updateView()被调用后,会重新构建课程,课程会回到当前周
*/
protected void hideNonThisWeek() {
mTimetableView.isShowNotCurWeek(false).updateView();
}
/**
* 显示非本周课程
* 修改了内容的显示,所以必须更新全部(性能不高)
* 建议:在初始化时设置该属性
*/
protected void showNonThisWeek() {
mTimetableView.isShowNotCurWeek(true).updateView();
}
/**
* 设置侧边栏最大节次,只影响侧边栏的绘制,对课程内容无影响
*
* @param num
*/
protected void setMaxItem(int num) {
mTimetableView.maxSlideItem(num).updateSlideView();
}
/**
* 显示时间
* 设置侧边栏构建监听,TimeSlideAdapter是控件实现的可显示时间的侧边栏
*/
protected void showTime() {
String[] times = new String[]{
"09:00", "10:20", "10:40", "12:00",
"12:30", "13:50", "14:00", "15:20",
"15:30", "16:50", "17:00", "18:20",
"19:00", "20:20", "20:30", "21:50"
};
OnSlideBuildAdapter listener = (OnSlideBuildAdapter) mTimetableView.onSlideBuildListener();
listener.setTimes(times)
.setTimeTextColor(Color.BLACK);
mTimetableView.updateSlideView();
}
/**
* 隐藏时间
* 将侧边栏监听置Null后,会默认使用默认的构建方法,即不显示时间
* 只修改了侧边栏的属性,所以只更新侧边栏即可(性能高),没有必要更新全部(性能低)
*/
protected void hideTime() {
mTimetableView.callback((ISchedule.OnSlideBuildListener) null);
mTimetableView.updateSlideView();
}
/**
* 显示WeekView
*/
protected void showWeekView() {
mWeekView.isShow(true);
}
/**
* 隐藏WeekView
*/
protected void hideWeekView() {
mWeekView.isShow(false);
}
/**
* 设置月份宽度
*/
private void setMonthWidth() {
mTimetableView.monthWidthDp(50).updateView();
}
/**
* 设置月份宽度,默认40dp
*/
private void resetMonthWidth() {
mTimetableView.monthWidthDp(40).updateView();
}
/**
* 修改显示的文本
*/
public void buildItemText() {
mTimetableView.callback(new OnItemBuildAdapter() {
@Override
public String getItemText(Schedule schedule, boolean isThisWeek) {
if (isThisWeek) return schedule.getName()+"["+schedule.getExtras().get(MySubject.EXTRAS_NUMBER)+"]"+"\n@"+schedule.getRoom();
return "[非本周]" + schedule.getName()+"["+schedule.getExtras().get(MySubject.EXTRAS_NUMBER)+"]"+"\n@"+schedule.getRoom();
}
})
.updateView();
}
/**
* 隐藏周末
*/
private void hideWeekends() {
mTimetableView.isShowWeekends(false).updateView();
}
/**
* 显示周末
*/
private void showWeekends() {
mTimetableView.isShowWeekends(true).updateView();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.id_layout:
//如果周次选择已经显示了,那么将它隐藏,更新课程、日期
//否则,显示
if (mWeekView.isShowing()) {
mWeekView.isShow(false);
titleTextView.setTextColor(getResources().getColor(R.color.app_course_textcolor_blue));
int cur = mTimetableView.curWeek();
mTimetableView.onDateBuildListener()
.onUpdateDate(cur, cur);
mTimetableView.changeWeekOnly(cur);
} else {
mWeekView.isShow(true);
titleTextView.setTextColor(getResources().getColor(R.color.app_red));
}
break;
}
}
}
登录:
如果勾选记住登录,则将学号以及密码存入SharedPreferences中,下次打开跳过登录直接显示课表,实现了离线操作,避免了需要再次联网登录爬取数据。
附:源码详见github
android Jsoup获取网站内容 android获取新闻标题实例
近期做简单的新闻客户端界面使用到了Jsoup获取,使用起来特别方便,这也是被我一个学长称为学android网络必学的一个东西,在此也是分享一下自己近期所学。
首先还是给出效果:
上面是通过textview显示的一个从网站上获取的所有内容的显示,下面是通过listview显示一下获取的新闻的标题,如此显示比较便于理解。
MainActivity:
import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.text.method.ScrollingMovementMethod; import android.util.Log; import android.view.Menu; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import java.util.ArrayList; import java.util.List; @SuppressWarnings("unused") public class MainActivity extends Activity { private TextView TV_HTMLCode; //此处搞一个TextView主要来显示News列表里面存储的内容,仅仅便于分析和理解 private String URL_EOL = "http://www.cnwust.com/newsList/1_1",TAG = "ATAG"; //这是索要获取内容的网址 private List<News> NewsList; //自定义的News的类,用于存放索要获取新闻的目录、时间以及点击后显示的网址 private ListView LV_Result; private ArrayAdapter<String> LV_Adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); LV_Result = (ListView) findViewById(R.id.LV_Result); TV_HTMLCode = (TextView) findViewById(R.id.TV_HTMLCode); TV_HTMLCode.setMovementMethod(ScrollingMovementMethod.getInstance()); ConnectTask C1 = new ConnectTask(); C1.execute(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main,menu); return true; } public class ConnectTask extends AsyncTask<Void,Void,String> { @Override protected String doInBackground(Void... params) { String result = ConnectEOL(); return result; } @Override protected void onPostExecute(String result) { // TV_HTMLCode.setText(result); NewsList = getNews(result); List<String> NewsTitles = new ArrayList<String>(); for (News news : NewsList) { TV_HTMLCode.append(news.getNewsTitle() + "\n"); TV_HTMLCode.append(news.getNewsTime() + "\n"); TV_HTMLCode.append(news.getNewsUrl() + "\n"); NewsTitles.add(news.getNewsTitle()); } /* 为ListView添加适配器 */ LV_Adapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,NewsTitles); LV_Result.setAdapter(LV_Adapter); /* 为ListView添加点击打开对应网页功能 */ LV_Result.setonItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0,View arg1,int arg2,long arg3) { final Uri uri = Uri.parse(NewsList.get(arg2).getNewsUrl()); final Intent it = new Intent(Intent.ACTION_VIEW,uri); startActivity(it); } }); //此处为了方便就点击就直接调用设备默认浏览器打开网址 super.onPostExecute(result); } } /* 连接EOL的方法 返回整个网页经过截取之后的的源代码 */ public String ConnectEOL() { String result = ""; try { HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(URL_EOL); HttpResponse response = httpclient.execute(httppost); String Res = EntityUtils.toString(response.getEntity(),"UTF-8"); int st = Res.indexOf("<div id=\"result\">"); int ed = Res.indexOf("<div id=\"pager\">"); //这边算是最重要的部分,代码获取的便是这两段之间的部分。 String content = Res.substring(st,ed); st = content.indexOf("<ul>") + 4; ed = content.indexOf("</ul>"); content = content.substring(st,ed); result = content; } catch (Exception e) { Log.d(TAG,e.toString()); } return result; } /* 对源代码进行解析截取的方法 返回一个News数组 */ public List<News> getNews(String HTMLCode) { List<News> newsList = new ArrayList<News>(); Document doc = Jsoup.parse(HTMLCode); Log.d(TAG,"解析html中"); Elements lis = doc.getElementsByTag("li"); Log.d(TAG,"lis的size " + lis.size()); for (Element li : lis) { String newstime = li.getElementsByTag("span").text(); String newstitle = li.getElementsByTag("a").text(); String newsurl = li.getElementsByTag("a").attr("href"); //这三段算是Jsoup从html中获取内容的关键了,很容易理解。 newsurl = newsurl.replace("/news","http://www.cnwust.com/news"); //直接从html的代码中获取的URL是相对路径,此处使用replace改为绝对路径 Log.d(TAG,newstime); Log.d(TAG,newstitle); Log.d(TAG,newsurl); News newst = new News(); newst.setNewsTime(newstime); newst.setNewsTitle(newstitle); newst.setNewsUrl(newsurl); newsList.add(newst); } return newsList; } }
News:
public class News { private String newsTime; private String newsUrl; private String newsTitle; public News() { } public News(String newsTitle,String newsTime,String newsUrl) { this.newsTime = newsTime; this.newsUrl = newsUrl; this.newsTitle = newsTitle; } public String getNewsTime() { return newsTime; } public void setNewsTime(String newsTime) { this.newsTime = newsTime; } public String getNewsUrl() { return newsUrl; } public void setNewsUrl(String newsUrl) { this.newsUrl = newsUrl; } public String getNewsTitle() { return newsTitle; } public void setNewsTitle(String newsTitle) { this.newsTitle = newsTitle; } }
activity_main:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".NewsList" > <TextView android:id="@+id/TV_HTMLCode" android:layout_width="match_parent" android:layout_height="150dp" android:layout_above="@+id/LV_Result" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:scrollbars="vertical" /> <ListView android:id="@+id/LV_Result" android:layout_width="match_parent" android:layout_height="230dp" android:layout_alignLeft="@+id/TV_HTMLCode" android:layout_alignParentBottom="true" > </ListView> </RelativeLayout>
此处对HTML代码的解析可能部分新手还是不太清楚,在此也是建议使用chrome浏览器,可以直接查看网站的源码。(有部分加密的网站看不到)下面看一下具体使用的截图:
1、首先先要打开到你要获取内容的网站
2、右击你要获取的内容,并选择 审查元素。
3、使用Jsoup解析HTML代码。
最后是附上源码下载地址
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
android studio实现小吃商城,android课程设设计
Android移动开发 课程设计
项目名称:小吃云商城(云小吃app)
源码文末获取
文章目录
- Android移动开发 课程设计
- 项目名称:小吃云商城(云小吃app)
- 1.任务要求
- 1.1 设计任务
- 1.2 设计要求
- 2.APP功能
- 2.1、登录页面
- 2.2、注册页面
- 2.3、密码修改页面
- 2.4、app 欢迎界面
- 2.5、app首页
- 2.6、小吃点分类点菜页
- 2.7、购物车页面及功能
- 2.8、删除购物车页面下
- 2.9、购物车单下单付款页面
- 2.10、“我的”个人中心页面
- 2.11、我的订单页面
- 2.12、地址管理页面
- 2.13、添加地址页面
- 2.14、删除地址页面
- 3.数据库设计
- 3.1、user表
- 3.2、orders表
- 3.3、address表
- 4.特色创意
- 5.1、清晰的程序结构
- 5.2、轮播图
- 5.3、ui设计
- 5.4、登录持久化
- 5.5、清晰的层次图如图 5.5-1
- 5.6、数据库ER图如图5.7-1
- 5.程序代码
1.任务要求
1.1 设计任务
本门课程的目的是训练运用移动开发技术,独立设计和开发APP的能力。本课程设计在完成移动开发技术等基础课程之后,集中一周时间让学生选择特定设计方案与内容独立完成Android APP设计与编程工作,以巩固和提高相关语法和相关应用技术。
1.2 设计要求
设计简单的APP。APP中至少包括5个以上的Activity页面。要求有数据库连接,并进行简单的交互。至少包括以下控件和元素:文本框、按钮、下拉列表、单选按钮、复选按钮、文本、ListView或GridView等。
2.APP功能
该APP包含个10个Activity,每个Activity的功能(附运行图)及写Activity的操作说明。
2.1、登录页面
登录活动的运行结果如图2.1所示。在文本框里填写密码后,如果账号与数据库账号匹配,对应的密码与数据库密码相匹配,则进入主页面。否则,提示密码用户名或者密码错误。
cdcfa4ce080c3fc40281a9bf8.png)
2.2、注册页面
用户点击新用户按钮来到软件注册页面,用户输入自己的注册信息,
当输入的用户名小于4位数时 将弹出提示用户名必须大于4 请重新输入,如图2.2-1
当用户输入的手机号步符合手机号标准时将弹出提示请输入11位手机号,如图2.2-2
当输入的密码少于6位数时将弹出提示密码为6-12位。同时将密码归空,如图2.2-3
当选择性别后将弹出提示所选中的性别如 图2.2-4
选择城市的方式为下拉列表,选中即可见 如 图2.2-5、
当信息已在数据库中已经注册过提示用户已存在如 图2.2-6
后端程序将对比两次密码是否一致 一致则才能注册成功
当输入信息正确后点击注册按钮 ,后端代码将注册信息写入数据库user表储存。用来记录用户信息和登录,浏览,下单操作。注册成功后将弹出提示注册册成功同时直接跳到登录页面如 图2.2-7
2.3、密码修改页面
当用户忘记自己的登录密码可以点击忘记密码按钮前往密码修改页面进行密码修改操作2.3-1
如果输入的信息在数据库中,并且用户输入符合的信息修改 密码修改成功后将弹出提示 修改成功同时自动跳回到登录页面 如图 2.3-2
如果修改用户步存在 弹出提示 用户名手机不匹配修改失败如图 2.3-3
在输入修改信息的时候页需要验证两次密码 如果账号存在输入的密码确认正确 则才能注册成功,如果两次密码不一致,则弹出提示两次密码不一致 修改失败 如图 2.3 -4
2.4、app 欢迎界面
当我们打开app 并非直接进入app 首页 而是先来到app 的欢迎页面。
这时一个app 最基本要有的功能。App欢迎页面如图 2.4-1
2.5、app首页
App首页 有小吃搜索功能 有广告轮播图 有小吃推荐序列 首页如图 2.5-1
可以点击浏览商品 并将收藏小吃和将小吃加入购物车 浏览完可以返回到上一页如图 2.5-2
2.6、小吃点分类点菜页
点击点菜页之后可以来到 分类点菜页面。
页面给将小吃按照城市分类,将全国各地有名小吃, 以列表的形式分类展现在用户面前。用户可以随意点击自己喜爱的城市的小吃, 页可以点击小吃进行详情浏览, 或直接点击有加号并将其加入到购入车内方便统一下单 。小吃分类浏览页面如图 2.6-1、2.6-3
2.7、购物车页面及功能
在购物车系统页面如果监测到购物查没有小吃上坪则显示 显示空空页的下单提示页 如图2.7-1
将小吃商品添加到购物车后,在购物车系统页面监测到有小吃数据,可以通过点击小吃页面上的 加号 和减号 改变小吃下单数量 ,购物车后端程序将自动计算出购物车的商品小吃价格合计并显示在页面上。 2.7-2
2.8、删除购物车页面下
进入购物车页面可以看到自己添加的小吃数据,接下来可以删除购物车数据,点击右下角的删除按钮将弹出弹窗提示删除确认,点击确认删除后可以删除购物车数据,当数据删除成功后,系统将弹出提示已清空数据库。然后回到空购物车页面。如图 2.8-1删除购物车数据确认图示 、2.8-2 购物车删除完成提示返回空页面图示
2.9、购物车单下单付款页面
进入购物车页面可以清晰的看到已经添加到购物车的数据,后端将计算出所有商品的价格合计。当用户点击用户下单支付后会跳出支付确认页面。在支付确认页面 用户可以添加备注信息,选择支付方式进行支付,app 将提供多种支付方式供用户选择。当用户支付成功后,系统后端程序将下单数据逐条添加到数据库中,作为用户下单凭据,和数据的保存方便,后续查看, 修改,删除等操作。同时下单成功后下单完成的数据也将从购物车数据中清楚。页面将提示下单成功。并且回到未下单或者空购物车显示页面给。
支付确认图如图 2.9-1 支付成功后提示与跳转页面给图示如图 2.9-2
2.10、“我的”个人中心页面
个人中心页面。个人中心是一个app必须应该具备的页面。在我们的云小吃app来到个人中心页面可以看到自己的账号信息(用户名,和id,头像信息)。在我的页面有查看订单,查看待付款,查看待评价,查看退款、支付设置地址管理修改地址通用设置 、退出登录 等功能。“我的”页面如图 2.10-1
在“我的”页面,如果你是未登录状态。将不能看到自己的个人信息,页面账号信息处将提示为未登录。如果点击页面上的功能入口后,后端程序将先判断当前是否为账号登录状态,如果未登录状态,系统将提示 当前未登录 并且不能进入查看相关内容。因为点击功能模块是查看和操作与账号相关的内容,未登录状态系统找不到要执行用户的操作,就将提示“未登录”。如图2.10-2
如果用户已经登录后将查看到自己的信息内容。后端程序将登录信息持久化并返回islogin 当需要执行操作时会先判断当前是否为登录状态。在登录状态下用户点击头像是将弹出提示:“已登录”。并能点击相关功能入口,查看和操作相关数据内容。
登录状态如图 2.10-3 。登录后可以点击页面相关功能入口查看相关和操作相关内容,如图2.10-4点击我的订单页面。登录成功后点击退出登录将退回到未登录状态页面。
2.11、我的订单页面
我的订单页面是查看我们下单成功后的小吃页面。当用户点击“我的订单”后后端程序将根据当前登录用户的账号查询数据库中该用户的订单记录显示到订单页面上。顶订单页面可查看订单信息。搜索查找订单信息。可以对订单进行相关删除、退款等管理操作。在订单页面点击左上角返回按钮将返回到上一个页面。订单页面如图 2.11-1
2.12、地址管理页面
在“我的”页面点击地址管理将跳转到地址管理页面,后端程序根据当前用户名查询用户的地址信息并将用户的地址信息显示到地址管理页面。用户可以点击地址信息进行地址管理的修改和删除操作。在地址管理页面点击添加地址将进入地址添加页面。
地址管理页面如图:2.12-1,点击地址跳转删除确认如图 2.12-2.
2.13、添加地址页面
在地址管理页面点击添加地址进入地址增加页面。用户在地址添加页面输入地址信息后,点击添加按钮,后端程序将地址信息添加到数据库地址表(address)中存储,添加成功后页面将弹出提示“添加成功”并返回到查看页面。方便地址的管理。
添加地址页面如图 2.13-1,地址添加成功如图 2.13-2。
2.14、删除地址页面
在地址管理中点击相应的低画质 可以进入到删除地址界面。用户可以点击删除确认 删除自己不用的地址信息。后台将根据地址id 删除对应的数据库中的内容。
地址删除如图 2.14-1 删除后成功提示 如图 2.14-2.
3.数据库设计
sqlite数据库名为OrderStore.db。共有3个表,表名分别为:user(用户数据表)、orders(订单数据面表)、address(地址数据表)。
3.1、user表
usert表记录用户注册信息,表结构如下表3.1所示。
3.2、orders表
orders表记录用户订单信息,表结构如图3.2-1
3.3、address表
address表记录用户地址信息。表结构如图3.3-1
4.特色创意
5.1、清晰的程序结构
@H_429_301@
5.2、轮播图
主要代码
乱播控件布局
<ViewFlipper
android:id="@+id/flipper"
android:layout_width="match_parent"
android:layout_height="200dp"
android:outAnimation="@anim/left_in"
android:inAnimation="@anim/right_out"
tools:ignore="MissingConstraints">
<ImageView
android:id="@+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:src="@drawable/lunbotu3" />
<ImageView
android:id="@+id/imageView2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:src="@mipmap/orderguanggao" />
<ImageView
android:id="@+id/imageView3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:src="@drawable/sack" />
<ImageView
android:id="@+id/imageView4"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:src="@drawable/lunbotu2" />
</ViewFlipper>
Java中的主要代码
ViewFlipper flipper;
flipper = findViewById(R.id.flipper);
flipper.startFlipping();
资源文件
设置轮播效果进出方向及时间
left_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="1000"
android:fromXDelta="100%p"
android:toXDelta="0" />
</set>
right_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="1000"
android:fromXDelta="0"
android:toXDelta="-100%p"/>
</set>
5.3、ui设计
5.4、登录持久化
主要代码
* 登录状态
*/
private static boolean isLogin;
public static MyApplication getInstance() {
return appContext;
}
public static List<Snack> getCartSnacks() {
return cartSnacks;
}
public static User getUser() {
return user;
}
public static void setUser(User user) {
MyApplication.user = user;
}
/**
* 是否登录
*
* @return <tt>true</tt>: 已经登录,<tt>false</tt>: 未登录
*/
public static boolean isLogin() {
return isLogin;
}
public static void isLogin(boolean isLogin) {
MyApplication.isLogin = isLogin;
}
// 登录运行
private void checkLogin() {
// 检查持久化的数据
if (UserDao.isLogin()) {
// 已登录
MyApplication.isLogin(true);
MyApplication.setUser(UserDao.getUser());
} else {
// 未登录
MyApplication.isLogin(false);
MyApplication.setUser(null);
}
}
5.5、清晰的层次图如图 5.5-1
图5.6-1、层次图
5.6、数据库ER图如图5.7-1
5.程序代码
代码太长 我已打包到云端
下载源码
总结
以上是小编为你收集整理的android studio实现小吃商城,android课程设设计全部内容。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。
原文地址:https://blog.csdn.net/hjjshua
android – 使用jsoup从网站网址中提取youtube视频网址
我有这个代码工作在同一个网站,但他们改变了主题,现在我正在努力.我在这里弄错了什么来获取YouTube视频的网址?这是我的方法.该站点的示例链接是http://kabumbu.co.tz/mahojiano-na-masau-bwire/
Element video = doc.select("div.single-archive iframe").first() ;
videourl = video.attr("src");
解决方法:
到目前为止,代码是正确的,但我只是错误地从视频网址中提取视频ID.使用这种方法有效
public static String extractVideoId(String ytUrl) {
String vId = null;
Pattern pattern = Pattern.compile(".*(?:youtu.be\\/|v\\/|u\\/\\w\\/|embed\\/|watch\\?v=)([^#\\&\\?]*).*");
Matcher matcher = pattern.matcher(ytUrl);
if (matcher.matches()){
vId = matcher.group(1);
}
return vId;
}
android – 使用JSoup获取表行
我使用JSoup与Android,到目前为止我已经成功.在我的原始活动中,我引用了一个表,并通过代码从表中的每个单元格引用.我的问题是如何让Jsoup根据某些参数获取表的结果?
例如,如果我想获得表的第3行 – (获取其内容).除了Jsoup网站上的任何资源之外,我会发现很难遵循的资源.
谢谢
解决方法:
你可以这样做:
String html = "<table id=\"myTable\"><tr><td>First</td></tr><tr><td>Second</td></tr><tr><td>Third</td></tr></table>";
Document doc = Jsoup.parse(html);
System.out.println(doc.select("#myTable").select("tr").get(1));
输出:
<tr>
<td>Second</td>
</tr>
这是表格中的第二行.
今天关于使用jsoup爬取数据实现android课程表和python爬取课表的讲解已经结束,谢谢您的阅读,如果想了解更多关于android Jsoup获取网站内容 android获取新闻标题实例、android studio实现小吃商城,android课程设设计、android – 使用jsoup从网站网址中提取youtube视频网址、android – 使用JSoup获取表行的相关知识,请在本站搜索。
本文标签: