近在设计筛选相关页面的时候,找来了一些参考。发现这种竟然有这么多不同种类的筛选设计类型,虽然以前在使用APP的时候也注意到过,但是用用就忘记了。正好找机会进行了下总结归类,以后在碰到类似设计的时候能够快速思考对应哪种类型的设计比较合适。
大致我进行了如下分类:
标签式筛选我们是最为常见的,比较典型的是在搜索页面筛选中被广泛使用。怎么运用这里就不多说了,大家都非常熟悉。
如下图:
我们在日常生活类购物的时候,例如购买日用品、食物、便利商品的时候经常会看到这种左侧导航式筛选、这种导航式筛选比较适合品种类目特别多,层级分类较深的时候。
单一层级如上图两鲜的APP,类似这种生活便利型的的APP最为常见,多层级的我们可以看下右上图的设计。
这种设计的好处是对于相对复杂的层级分类,能够清晰有条理的收纳。可以尽可能多的展示更多入口,尤其是对于购物类的APP能够增加多频道的流量,当然流量也可以转换更多的交易量。
下拉式筛选分为:下拉弹窗、下拉卡片式筛选、下拉菜单加左侧列表层叠式。
(1)下拉弹窗
我们可以看到上图左一哔哩哔哩采用的下拉弹窗,这种样式是筛选中比较常见的,最为普通的是单一层下拉弹窗,但这里哔哩哔哩运用了层叠式的筛选形式,在设计上上面一排跟下面一排除了文字大小并没有太大的区分,体验很差,再加上下拉弹窗一大堆的文字分类,密集恐惧症有没有。
(2)下拉卡片式筛选
那么我们再来看看京东同样运用了层叠式的下拉弹窗设计,第一排跟第二排设计上有了明显的区分,第二排采用了底板标签式样,很好的区分了上下的层次感,另外一点为了进一步加深区分,利用矩形标签的形状,采用了卡片式的选项卡分类设计。信息虽多但每一个细节的层次感区分明显,不失为好的设计。
(3)下拉菜单加左侧列表层叠式
这种筛选形式首先采用了之前说的列表层叠式样式,同时它又是下拉菜单的形式。我们再次跟哔哩哔哩的设计进行对比,如果像哔哩哔哩这种信息模块特别多的情况,其实可以对三级菜单进行再次归类,结合左侧列表层叠的样式进行设计。或是借鉴下京东的层次区分的设计,展示效果会大大提升。
折叠式筛选在网页端运用的相对较多,其实在APP端用也非常好,因为这种形式如果第二层级分类不多,或者是第二层级信息量较少的情况下我们采用信息折叠的形式是比较好的。可以减少页面的跳转,用户只需要在当前页面获取信息或者是在当前页面进行筛选。
浮层引导式筛选常常用于首次进入APP的时候,帮助用户筛选出自己感兴趣的内容,之后方便后台进行数据统计,然后根据不同用户的喜好推送不同的内容。这样一劳永逸的筛选形式,避免了后期不必要的麻烦。而且全屏展示能够提供更大的展示空间。
横条式筛选包括:横条标尺型筛选、横条进度条型筛选
(1)横条标尺型筛选
上图左一是京东金融的小白理财页面,采用了比较新颖的标尺进行投资额的设定,用户只需要左右滑动即可,可操作性很强,避免了用户填写数值的反感情绪。
(2)横条进度条型筛选
右上图采用了进度条的设计,用户拖动滑块即可确定数值,操作上没有标尺型那样灵活,但适合用于弹窗或者是小的模块上。
弹窗式筛选主要分为:弹窗型筛选和底部弹窗型筛选
(1)弹窗型筛选
弹窗型的筛选一般来说还是比较少见的,通常情况下还是慎用,因为弹窗会打断用户浏览当前页面,影响操作的连贯性。类似于这种情况呢,我就建议使用下拉弹窗式筛选或者右侧抽屉式筛选效果会更好,也不会打断用户对整个页面的预览。
(2)底部弹窗型筛选
上右图的底部弹窗式筛选这种方式通常用于底部菜单栏的操作二级筛选展示,这种就比用弹窗型筛选好很多,把对整个页面的干扰降到最低。
填鸭式筛选通常用于多选情况比较多,当然也有单选的时候,还有填写调查问卷或者测试题的时候。
我们可以看到上图左的底部弹窗填鸭式筛选,右侧对筛选项目进行了选中的高亮型设计,层次感非常好。这种模拟填鸭的形式模拟了真实的习题选择,可视化较强,是一种不错的设计形式。
我们再来看看右图的字母选项卡填鸭式设计,这个药品的分类就很好,同样类似于上面哔哩哔哩面临入口模块繁杂的情况。
一般这种精细化的选择的目标用户是深度用户,有明确目的性的。漫无目的的用户不会去筛选这么复杂的操作。所以这里巧妙的结合运用了字母选项卡的设计,然后对信息入口进行了归类整合分隔展示,整个页面看起来更有逻辑调理。
日期筛选分为:滚动式和日历式。
(1)滚动式筛选
日期滚动式筛选是iOS里的日期筛选特性,也是极为常见的设计形式。这种筛选形式有点像密码锁,操作趣味性强,降低用户填写数字的负面情绪。但是记得在我之前工作的时候层级采用了日期滚动式设计,在进行安卓后期的调整的时候发现开发告知我安卓没办法做出具有景深的滚动效果。那么视觉效果就大打折扣了。
实际上安卓的设计规范Material Design采用的是菜单原地展开,盖住当前选项,当前选项成为菜单的第一项的设计形式。并非iOS的滚动式筛选,如下图所示。
所以我们运用滚动式设计形式的时候,记得要考虑iOS跟安卓的平台差异性。
(2)日历筛选
日历筛选是另一种日期筛选形式,这种形式适合运用在购买机票火车票,或者是期刊专题类设计的页面上。因为有时候可能我们并不是很明确要选择哪个日期,尤其是买飞机票我们要看不同日期的不同票价进行比对。还有期刊专题我们回顾往期期刊的时候,并不会明确的记得哪个日期没有看。这时候就需要可视化更强的设计,日历筛选。
右侧抽屉式设计其实是比较综合类的筛选设计,通常情况下跟下拉式弹窗设计结合使用。通常展示了不同的筛选形式,例如标签式筛选、折叠式筛选、填鸭式筛选等等。总之当我们需要展示不同筛选形式的时候推荐使用右侧抽屉式筛选设计。
这里我们针对不同的使用场景总结出了十大筛选类型,分别为:标签式筛选、左侧导航式筛选、下拉式筛选、折叠式筛选、浮层引导式筛选、横条式筛选、弹窗式筛选、填鸭式筛选、日期筛选、右侧抽屉式筛选。
相信我们在以后设计筛选模块的时候不至于束手无策了,希望本篇对您有帮助!
作者:角马X ,口袋理财UED设计经理 公众号:海盐社
本文由 @角马X 原创发布于人人都是产品经理。未经许可,禁止转载
题图来自Unsplash,基于CC0协议
eb爬取是从Web上收集和解析数据的过程。Python社区已经开发出一些非常强大的web爬取工具。其中,Pandas read_html()是从html表中爬取数据的一种快速方便的方法。
在本文中,你将学习Pandas read_html()来处理以下常见问题,并帮助你进行web爬取。
1.从字符串读取表
2.从URL读取表
3.从文件读取表
4.使用parse_dates分析日期列
5.使用converters显式转换类型
6.多索引、标题和索引列
7.用match匹配表
8.使用属性筛选表
9.使用缺失值
请检查Notebook的源代码(https://github.com/BindiChen/machine-learning/blob/master/data-analysis/024-pandas-read_html/pandas-read_html.ipynb)。
在第一个示例中,我们将从字符串中读取HTML表。
html_string="""
<table>
<thead>
<tr>
<th>date</th>
<th>name</th>
<th>year</th>
<th>cost</th>
<th>region</th>
</tr>
</thead>
<tbody>
<tr>
<td>2020-01-01</td>
<td>Jenny</td>
<td>1998</td>
<td>0.2</td>
<td>South</td>
</tr>
<tr>
<td>2020-01-02</td>
<td>Alice</td>
<td>1992</td>
<td>-1.34</td>
<td>East</td>
</tr>
<tr>
<td>2020-01-03</td>
<td>Tomas</td>
<td>1982</td>
<td>1.00023</td>
<td>South</td>
</tr>
</tbody>
</table>
"""
要从字符串中读取表,请执行以下操作:
dfs=pd.read_html(html_string)
现在,我们得到的结果不是Pandas数据帧而是Python列表。如果使用type()函数,可以看到:
>>> type(dfs)
list
如果要获取表,可以使用索引访问它:
dfs[0]
结果看起来很棒。让我们看看dfs[0].info()的数据类型。默认情况下,数值列被转换为数值类型,例如,year和cost列分别被转换为int64和float64。
>>> df[0].info()
RangeIndex: 3 entries, 0 to 2
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 date 3 non-null object
1 name 3 non-null object
2 year 3 non-null int64
3 cost 3 non-null float64
4 region 3 non-null object
dtypes: float64(1), int64(1), object(3)
memory usage: 248.0+ bytes
Pandas read_html()接受URL。让我们通过一个例子来看看这是如何工作的。
URL='https://en.wikipedia.org/wiki/London'
dfs=pd.read_html(URL)
与从字符串读取相同,它返回一个数据帧列表。如果我们运行len(dfs),我们可以从给定的URL得到31个表。
>>> print(f'Total tables: {len(dfs)}')
31
下面是dfs[6]的一个例子:
Pandas read_html()接受一个文件。让我们通过一个例子来看看这是如何工作的。
file_path='html_string.txt'
with open(file_path, 'r') as f:
dfs=pd.read_html(f.read())
dfs[0]
注意:以下教程将从字符串中读取数据,因为随着时间的推移,网页内容可能变更。
日期列作为对象数据类型读取。要正确读取日期列,可以使用参数parse_dates指定日期列的列表。
>>> dfs=pd.read_html(html_string, parse_dates=['date'])
>>> dfs[0].info()
RangeIndex: 3 entries, 0 to 2
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 date 3 non-null datetime64[ns]
1 name 3 non-null object
2 year 3 non-null int64
3 cost 3 non-null float64
4 region 3 non-null object
dtypes: datetime64[ns](1), float64(1), int64(1), object(2)
memory usage: 248.0+ bytes
默认情况下,数值列被转换为数值类型,例如,我们看到的year和cost列。但并非所有的数字文本数据都必须是数字类型,例如,所有值都以零开头的ID列。
ID=0001
此外,有时可能需要显式地进行类型转换以确保数据类型的完整性。对于这些要求,我们可以使用参数转换器显式地进行类型转换:
dfs=pd.read_html(html_string, converters={
'ID': str,
'year': int,
'cost': float,
})
默认情况下,位于<thead>中的<th>或<td>元素用于形成列索引,如果<thead>中包含多行,则创建一个多索引。
下面是一个在<thead>中包含多行的HTML表的示例。
html_string="""
<table>
<thead>
<tr>
<th colspan="5">Year 2020</th>
</tr>
<tr>
<th>date</th>
<th>name</th>
<th>year</th>
<th>cost</th>
<th>region</th>
</tr>
</thead>
<tbody>
<tr>
<td>2020-01-01</td>
<td>Jenny</td>
<td>1998</td>
<td>1.2</td>
<td>South</td>
</tr>
<tr>
<td>2020-01-02</td>
<td>Alice</td>
<td>1992</td>
<td>-1.34</td>
<td>East</td>
</tr>
</tbody>
</table>
"""
它创建多重索引,因为<thead>中有多行。
dfs=pd.read_html(html_string)
dfs[0]
指定标题行:
dfs=pd.read_html(html_string, header=1)
dfs[0]
指定索引列:
dfs=pd.read_html(html_string, header=1, index_col=0)
dfs[0]
参数匹配采用字符串或正则表达式。该值默认为.+(匹配任何非空字符串),并将返回所有表。
我们通过一个例子来看看这是如何工作的。
html_string="""
<table id="report">
<caption>2020 report</caption>
<thead>
<tr>
<th>date</th>
<th>name</th>
</tr>
</thead>
<tbody>
<tr>
<td>2020-01-01</td>
<td>Jenny</td>
</tr>
<tr>
<td>2020-01-02</td>
<td>Alice</td>
</tr>
</tbody>
</table>
<table>
<caption>Average income</caption>
<thead>
<tr>
<th>name</th>
<th>income</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tom</td>
<td>200</td>
</tr>
<tr>
<td>James</td>
<td>300</td>
</tr>
</tbody>
</table>
"""
要读取包含特定文本的表:
# 标题中的文本
dfs=pd.read_html(html_string, match='2020 report')
# 表格单元格中的文本
dfs=pd.read_html(html_string, match='James')
参数attrs接受任何有效的HTML标记属性的字典来筛选表。例如:
dfs=pd.read_html(html_string, attrs={'id': 'report'})
id是有效的HTML标记属性。
默认情况下,所有空字符串都被视为缺失值,并作为NaN读取。
下面是一个HTML表格的示例,其中的< td >单元格中有一些空字符串。
html_string="""
<table>
<tr>
<th>date</th>
<th>name</th>
<th>year</th>
<th>cost</th>
<th>region</th>
</tr>
<tr>
<td>2020-01-01</td>
<td>Jenny</td>
<td>1998</td>
<td>1.2</td>
<td>South</td>
</tr>
<tr>
<td>2020-01-02</td>
<td>Alice</td>
<td>1992</td>
<td></td>
<td>East</td>
</tr>
<tr>
<td>2020-01-03</td>
<td>Tomas</td>
<td>1982</td>
<td></td>
<td>South</td>
</tr>
</table>
"""
以默认设置读取。
dfs=pd.read_html(html_string)
dfs[0]
为了保留这些空字符串,我们可以将参数keep_default_na设置为False。
dfs=pd.read_html(html_string, keep_default_na=False)
有时,对于缺少的值,你可能有其他字符表示法。如果我们知道什么类型的字符用作表中的缺失值,我们可以使用na_values参数处理它们:
dfs=pd.read_html(html_string, na_values=['?', '&'])
当数据帧已经创建好后,我们可以使用pandas replace()函数来处理这些值:
df_clean=dfs[0].replace({ "?": np.nan, "&": np.nan })
Pandas read_html()函数是一种快速方便地从html表中获取数据的方法。
我希望本文能帮助你节省从HTML表中删除数据的时间。建议你查看read_html()API的文档,并了解可以做的其他事情。
谢谢你的阅读。请查看Notebook的源代码,如果你对机器学习的实际方面感兴趣,请继续关注:https://github.com/BindiChen/machine-learning/blob/master/data-analysis/024-pandas-read_html/pandas-read_html.ipynb。
、筛选请求
Show all Content-Type:显示所有类型Content-Type的请求,Content-Type即为响应结果header信息中Content-Type字段
Show only IMAGE/*:仅显示响应类型为图片的请求
Show only HTML:仅显示响应类型为HTML的请求
Show only TEXT/CSS:仅显示响应类型为text/css的请求
Show only SCRIPTS:仅显示响应类型为Scripts的请求
Show only XML:仅显示响应类型为XML的请求
Show only JSON:仅显示响应类型为Json的请求
Hide IMAGE/*:隐藏所有响应类型为图片的请求
二、修改请求参数之临时修改参数
三、断点修改请求参数
四、通过Composer修改参数
五、修改请求参数之永久修改参数,FiddlerScript修改参数
六、修改请求脚本代码
if (oSession.HTTPMethodIs("POST") && oSession.uriContains("example.com")) {
// 获取请求的 Body 数据
var requestBody=oSession.GetRequestBodyAsString();
// 解析 JSON
var json=Fiddler.WebFormats.JSON.JsonDecode(requestBody);
// 修改 JSON 参数
json.JSONObject["Body"]["kwy"]="value";
// 删除 JSON 参数
json.JSONObject.Remove('key');
json.JSONObject["Body"].Remove("key");
// 将修改后的 JSON 转换回字符串
var modifiedRequestBody=Fiddler.WebFormats.JSON.JsonEncode(json.JSONObject);
// 更新请求的 Body 数据
oSession.utilSetRequestBody(modifiedRequestBody);
}
if (oSession.HTTPMethodIs("POST") && oSession.uriContains("example.com")) {
// 获取请求的 Body 数据
var requestBody=oSession.GetRequestBodyAsString();
// 修改参数
requestBody=requestBody.replace("param1=value1", "param1=newValue");
// 更新请求的 Body 数据
oSession.utilSetRequestBody(requestBody);
}
if (oSession.HTTPMethodIs("GET") && oSession.uriContains("example.com")) {
// 获取请求的 URL
var url=oSession.fullUrl;
// 修改参数
url=url.replace("param1=value1", "param1=newvalue");
// 更新请求的 URL
oSession.fullUrl=url;
}
import System.Web;
if (oSession.HTTPMethodIs("GET") & & oSession.uriContains("example.com")) {
// 获取请求的 URL
var url=oSession.fullUrl;
// 解析 URL 中的参数
var uri=new System.Uri(url);
var queryString=System.Web.HttpUtility.ParseQueryString(uri.Query);
// 删除指定的参数
queryString.Remove("dt");
// 构建新的 URL
var newUrl=uri.GetLeftPart(System.UriPartial.Path) + "?" + queryString.ToString();
// 更新请求的 URL
oSession.fullUrl=newUrl;
}
if (oSession.HTTPMethodIs("GET") && oSession.uriContains("example.com")) {
// 获取请求的头部对象
var headers=oSession.oRequest.headers;
// 修改头部的值
headers["key"]="value";
// 删除指定的头部
headers.Remove("key");
}
if (oSession.HTTPMethodIs("GET") && oSession.uriContains("example.com")) {
// 获取请求的 Cookie 值
var cookieValue=oSession.oRequest["Cookie"];
// 添加cookie
cookieValue+=";key=value";
// 修改cookie
cookieValue=cookieValue.Replace("key=value", "key=newValue");
// 删除cookie
cookieValue=cookieValue.Replace("key=value", "");
oSession.oRequest["Cookie"]=cookieValue
}
if (oSession.HTTPMethodIs("GET") && oSession.uriContains("example.com")) {
// 获取请求的 Cookie 值
var cookieValue=oSession.oRequest["Cookie"];
var pattern="key=([^&]*)";
var regex=new System.Text.RegularExpressions.Regex(pattern);
var cookieValue=regex.Replace(cookieValue, "key=newValue");
oSession.oRequest["Cookie"]=cookieValue
}
FiddlerApplication.Log.LogString("cookie: " + cookieValue);
*请认真填写需求信息,我们会在24小时内与您取得联系。