Java爬虫快速开发工具uncs的部署攻略
写在前面
uncs是java快速开发爬虫的工具,简单便捷,经过大量版本迭代和生产验证,可以适用大多数网站,推荐使用。
一、基本用法
1.1 开发包获取
目前只能在公司内网maven服务器获取到
<dependency> <groupId>com.cdc</groupId> <artifactId>uncs</artifactId> <version>3.0.0.6</version> </dependency>
1.2 开发单步流程
步骤一
package com.cdc.uncs.service.parts; import com.cdc.uncs.exception.UncsException; import com.cdc.uncs.model.HttpCrawlInfo; import com.cdc.uncs.model.TestRequest; import com.cdc.uncs.model.TestResponse; import com.cdc.uncs.service.NetCrawlPart; import com.cdc.uncs.service.TransContext; public class NetCrawlTestPart extends NetCrawlPart<TestRequest, TestResponse> { @Override public void beforeCrawl(TransContext<TestRequest, TestResponse> context, HttpCrawlInfo crawlInfo, String crawlId, String type) throws UncsException { String url = "http://www.baidu.com"; crawlInfo.setUrl(url); } @Override public void afterCrawl(TransContext<TestRequest, TestResponse> context, HttpCrawlInfo crawlInfo, String crawlId, String type) throws UncsException { System.out.println(crawlInfo.getHttpCrawlResult()); } }
步骤二
package com.cdc.uncs.service.parts; import com.cdc.uncs.exception.UncsException; import com.cdc.uncs.model.HttpCrawlInfo; import com.cdc.uncs.model.TestRequest; import com.cdc.uncs.model.TestResponse; import com.cdc.uncs.service.NetCrawlPart; import com.cdc.uncs.service.TransContext; public class NetCrawlTestPart2 extends NetCrawlPart<TestRequest, TestResponse> { @Override public void beforeCrawl(TransContext<TestRequest, TestResponse> context, HttpCrawlInfo crawlInfo, String crawlId, String type) throws UncsException { String url = "http://www.hao123.com"; crawlInfo.setUrl(url); } @Override public void afterCrawl(TransContext<TestRequest, TestResponse> context, HttpCrawlInfo crawlInfo, String crawlId, String type) throws UncsException { System.out.println(crawlInfo.getHttpCrawlResult()); } }
1.3 服务配置文件
uncsTestApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://uncs.cdc.com/schema/uncs http://uncs.cdc.com/schema/uncs/springuncs.xsd" xmlns:uncs="http://uncs.cdc.com/schema/uncs" default-autowire="byName"> <uncs:crawl id=" proxyType="no"> <uncs:list> <uncs:netCrawlPart class="com.cdc.uncs.service.parts.NetCrawlTestPart" desc="登陆"/> <uncs:netCrawlPart class="com.cdc.uncs.service.parts.NetCrawlTestPart2" desc="获取"/> </uncs:list> </uncs:crawl> </beans> demo样例 // ----------------------系统启动--------------------------- // 用户自定义的服务配置文件 String xmlTest = "classpath*:uncsTestApplicationContext.xml"; // 启动uncs的初始化参数 redis:ip、port socks5:ip、port 项目缩写 http代理 获取http代理超时时间 代理类型 InitParam param = , , , "no"); // 启动uncs param:启动参数 xmlTest...:服务配置文件,可以是多个 UncsLancher.startUp(param, xmlTest); // ----------------------调用服务-------------------------- // 定义上下文,贯穿整个服务 TransContext<TestRequest, TestResponse> transContext = TransContext.newInstance(TestRequest.class, TestResponse.class); // crawlId:单个爬取交易的唯一索引 String crawlId = Long.toString(System.currentTimeMillis()); // type:交易的类型,辅助参数,用户自定义。例如爬取时可以把类型作为type,可以贯穿整个交易 String type = "xxx"; transContext.setCrawlId(crawlId); transContext.setType(type); // 服务名称,对应配置文件中uncs:crawl标签的id String serverName = "testService"; // 开始执行交易 TestResponse response = UncsService.startService(serverName, transContext);
二、约定
crawlId必输,贯穿整个服务
流程内的步骤实现类必须继承相关父类
暂时必须使用redis为框架提供支持,以后会开发不需要redis的单机版本
三、设计思想
基于流程化的爬虫开发框架,参数动态可配置化,可扩展。能不让用户关心的,就不需要用户去考虑,屏蔽一切可以屏蔽的细节.
四、配置详解
4.1 crawl交易配置
uncs:crawl标签
attr:
id:唯一服务名,例:testService
browser:浏览器类型,枚举:Chrome51(chrome浏览器),IE9,IE8,FIREFOX,DEFAULT,默认是chrome浏览器,设置这个属性,代码就不需要设置http header的user-agent了
poolSize:服务运行时线程池大小即这个服务支持的并发大小,如果不设置,则使用公共的线程池
proxyType:代理类型,no-不使用代理 http:使用http代理 socks:socks5代理 default-http:默认的http代理 default-socks:默认的socks代理 (两个默认的代理类型在初始化参数InitParam设置)
property:
uncs:list--流程列表,服务按顺序执行配置的实现类列表,list内支持所有类型的part
uncs:finalPart--流程完成后,不管成功还是失败,都会执行的步骤
uncs:proxyService--扩展的代理服务,用户可以自定义bean,来编写自己的代理服务,当uncs:crawl的attr-proxyType设置为http或socks时,系统会加载这个标签的代理服务,详细参考“代理配置及使用”章节
4.2 part
所有模板步骤的父类,空模板,可以自由发挥
步骤:建立java类-->继承com.cdc.uncs.service.Part-->重写work方法-->配置文件
当这个步骤可能不需要执行时,重新isPassPart方法,返回true即跳过,所有子类模板都有这个步骤
对应配置文件标签:uncs:part class--实现类 desc--步骤名称,不填默认为类名简写
4.3 netCrawlPart
网络爬取步骤模板,用户使用此模板就不用关心httpclient如何使用了
步骤:建立java类-->继承com.cdc.uncs.service.NetCrawlPart-->重写beforeCrawl和afterCrawl方法-->配置文件 beforeCrawl:爬取前组装http请求参数
设置方法内参数HttpCrawlInfo crawlInfo,来改变请求内容
属性名(一) | 详细(一) |
---|---|
method | post/get |
mineType | img-图片 json-暂不支持 html-文本 |
httpParamType | form-表单 string-纯字符串 |
url | 爬取的url |
referer | 来源页 |
charset | 编码,默认是utf-8 |
isRelocal | 是否自动跳转 |
params | 表单参数 |
stringParam | 当httpParamType为string时,才生效 |
headerParam | http header参数,支持Map方法和一个一个设置的方法,常用的header支持便捷设置方法,user-agent可以不设置,cookie不需要设置 |
httpCrawlResult/httpCrawlImgResult | 用于保存返回结果 |
cookies | 可以手工设置cookie |
relocalList | 当isRelocal为true时,页面跳转流程会在这保存 |
proxyService | 可以单独某个步骤设置代理 |
isNetErrThrow | 发生网络错误时,是否抛出异常,默认不抛 |
isLogResponse | 是否记录返回日志 |
e | 真正的异常对象 |
timeOut | 单步超时时间 |
isJdkSafe | 是否支持jdk1.7安全策略 |
tempInfo | 临时参数,用户部分http交互参数设置 |
tempInfo.usedProxy | 但步骤代理策略 |
tempInfo.responseCode | http返回码 |
tempInfo.proxyParam | 代理服务的参数 |
tempInfo.httpRetryMaxTimes | 失败后最大的重试次数 |
tempInfo.sslVersion | 指定ssl协议版本号 |
tempInfo.clearCookie | 是否清空cookie |
tempInfo.poolEntityAliveTime | http池化,每个链接存活时间 |
tempInfo.poolSize | http池化,池大小 |
afterCrawl:爬取后解析返回结果 HttpCrawlInfo crawlInfo.getHttpCrawlResult和getHttpCrawlImgResult获取返回结果
对应配置文件标签,uncs:netCrawlPart,class--实现类 desc--步骤名称,不填默认为类名简写 示例:
<uncs:crawl id=" proxyType="no"> <uncs:list> <uncs:netCrawlPart class="com.cdc.uncs.service.parts.NetCrawlTestPart" desc="网络爬取测试步骤"/> </uncs:list> </uncs:crawl>
java
package xxx; import xxx; /** * 加载查询 */ public class FlowQueryPart extends NetCrawlPart<FlowGetterRequest, FlowGetterResponse> { @Override public void beforeCrawl(TransContext<FlowGetterRequest, FlowGetterResponse> context, HttpCrawlInfo crawlInfo, String s, String s1) throws UncsException { String url = (String) context.getTempParamValue(ParamKey.XXX); String referer = (String) context.getTempParamValue(ParamKey.REFXXX); crawlInfo.addAccept("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); crawlInfo.addAcceptEncoding("gzip, deflate, sdch"); crawlInfo.addAcceptLanguage("zh-CN,zh;q=0.8"); crawlInfo.addConnection("keep-alive"); crawlInfo.addHost("XXX.com"); crawlInfo.addParam("query", "true"); crawlInfo.addParam("q_from_date", (String) context.getTempParamValue(ParamKey.BEGIN_DATE)); crawlInfo.addParam("q_to_date", (String) context.getTempParamValue(ParamKey.END_DATE)); crawlInfo.setCharset(CoreConstant.CHARSET); crawlInfo.setMineType(MineType.HTML); crawlInfo.setMethod(HttpMethod.GET); crawlInfo.setUrl(url); crawlInfo.setReferer(referer); context.addTempParam(ParamKey.NEXT_REFERER, url); } @Override public void afterCrawl(TransContext<FlowGetterRequest, FlowGetterResponse> context, HttpCrawlInfo crawlInfo, String crawlId, String bankCode) throws UncsException { String result = crawlInfo.getHttpCrawlResult(); if(Strings.isNullOrEmpty(result)) { throw new SystemUncsException("网页加载错误", ErrorCode.XXX); } } }
4.4 loopPart
循环步骤模板,已经过时的模板,被complexLoopPart复杂循环步骤模板替换,不再维护,可以使用,可能存在一些BUG,只支持单步骤循环
4.5 switchPart
选择步骤模板,类似java的switch,支持根据不同场景走不同分支步骤 场景举例:某网站爬取时,需要根据归属地省份的不同走不同的分支爬取 配置样例:
<uncs:crawl id=" proxyType="no"> <uncs:list> <!-- choosePartClass必须继承com.cdc.uncs.service.ChooseKeyPart --> <uncs:switchPart choosePartClass="com.cdc.uncs.service.parts.ChooseKeyTestPart" choosePartDesc="选择key测试步骤"> <uncs:entity key="bj"> <uncs:list> <uncs:netCrawlPart class="com.cdc.uncs.service.parts.NetCrawlTestPart" desc="北京"/> </uncs:list> </uncs:entity> <uncs:entity key="sh"> <uncs:list> <uncs:netCrawlPart class="com.cdc.uncs.service.parts.NetCrawlTestPart2" desc="上海"/> </uncs:list> </uncs:entity> </uncs:switchPart> </uncs:list> </uncs:crawl>
代码样例:
package xxxx; import xxxx; public class ChooseKeyTestPart extends ChooseKeyPart<TestRequest, TestResponse> { @Override public boolean isPassPart(TransContext<TestRequest, TestResponse> context) { // 不需要发送网络请求在这实现 chooseKey("bj"); return true; } @Override public void beforeCrawl(TransContext<TestRequest, TestResponse> context, HttpCrawlInfo crawlInfo, String crawlId, String mobileType) throws UncsException { // 需要发送网络请求来判断的才需要实现 } @Override public void afterCrawl(TransContext<TestRequest, TestResponse> context, HttpCrawlInfo crawlInfo, String crawlId, String mobileType) throws UncsException { } }
4.6 groupRetryPart
组重试步骤,可以实现整个步骤组重试,可设置最大重试次数,是否重试需要用户根据实际场景调用重试方法。 场景举例:识别图片验证码成功率不是百分百,当失败时需要重新识别,重新验证 配置样例:
<uncs:crawl id=" proxyType="no"> <uncs:list> <!-- betweenMillis重试间隔时间(毫秒) maxRetryTimes最大重试次数 --> <uncs:groupRetryPart betweenMillis="> <uncs:list> <uncs:netCrawlPart class="com.cdc.uncs.service.parts.NetCrawlTestPart" desc="网络爬取测试步骤"/> </uncs:list> </uncs:groupRetryPart> </uncs:list> </uncs:crawl>
注:重试次数超过最大重试次数时,需要由用户自行判断是否需要抛异常,默认不抛异常,流程正常执行 代码样例:
@Override public void afterCrawl(TransContext<FlowGetterRequest, FlowGetterResponse> context, HttpCrawlInfo crawlInfo, String crawlId, String bankCode) throws UncsException { String result = crawlInfo.getHttpCrawlResult(); if(Strings.isNullOrEmpty(result)) { throw new SystemUncsException("网页加载错误", ErrorCode.ERROR_3006); } // 校验结果 try { CCBBaseUtil.validateResult(result, crawlId, bankCode, this.getName(), log); } catch (UncsException e) { String code = e.getCode(); if(ErrorCode.ERROR_0000.equals(code)) { // 验证码错误,重试 // 验证重试次数 if(this.getGroupRetryCurrent(context) < this.getGroupRetryMax(context)) { // 重试 retry(); }else{ log.log(crawlId, this.getName(), bankCode, "图片验证码超过最大重试次数"); throw new SystemUncsException("图片验证码错误次数超限,请重试,并检查", ErrorCode.ERROR_2002); } } else { throw e; } } }
4.7 complexLoopPart
复杂循环步骤模板,类似java的循环,即支持for循环也支持while循环,默认是for循环,支持任何模板套用。 新增支持循环横向并发 场景举例: for循环,爬取某网站数据时,按月份循环爬取为第一层循环,每个月类型的分页为第二层循环 while循环,同for循环,区别在于银行的分支只有下一页,不知道总页数 配置样例:
<!-- loopType 循环类型 for/while 不填默认for preClass前置处理类,必须继承com.cdc.uncs.service.LoopPrePart,一般用做查询和设置最大循环次数,当然也可以在内部步骤内设置 isAsyn是否并发 asynThreadCount并发最大线程数 --> <uncs:complexLoopPart loopType="> <uncs:list> <uncs:netCrawlPart class="com.cdc.uncs.service.parts.NetCrawlTestPart" desc="复杂循环步骤"/> <uncs:netCrawlPart class="com.cdc.uncs.service.parts.NetCrawlTestPart2" desc="复杂循环步骤2"/> </uncs:list> </uncs:complexLoopPart>
代码样例:
@Override public void beforeCrawl(TransContext<TestRequest, TestResponse> context, HttpCrawlInfo crawlInfo, String crawlId, String mobileType) throws UncsException { // 获取当前循环次数 this.getComplexLoopCurrent(context); getCookieValue(crawlId, "BAIDUID"); String url = "http://www.baidu.com"; crawlInfo.setUrl(url); } @Override public void afterCrawl(TransContext<TestRequest, TestResponse> context, HttpCrawlInfo crawlInfo, String crawlId, String mobileType) throws UncsException { // 设置循环最大数次 ); System.out.println(crawlInfo.getHttpCrawlResult()); }
注:循环内部支持套用任何模板,但是只有循环内所属步骤才能操作循环的属性(最大页数、当前页数),循环内循环的步骤无法跨级操作。
4.8 finalPart
服务最终处理内容,无论成功失败都会执行的步骤。 场景举例:爬取某网站后,为防止对登录状态进行判断,需要在结束后退出登录 配置样例:
<uncs:crawl id=" proxyType="no"> <uncs:list> <uncs:complexLoopPart loopType="for" preClass="" preDesc=""> <uncs:list> <uncs:netCrawlPart class="com.cdc.uncs.service.parts.NetCrawlTestPart" desc="复杂循环步骤"/> <uncs:netCrawlPart class="com.cdc.uncs.service.parts.NetCrawlTestPart2" desc="复杂循环步骤2"/> </uncs:list> </uncs:complexLoopPart> </uncs:list> <uncs:finalPart> <uncs:part class="com.cdc.uncs.service.parts.NetCrawlTestPart" desc="退出"/> </uncs:finalPart> </uncs:crawl>
五、断点
uncs支持程序断点,即支持临时中断正在运行的服务,满足某种场景时,可以重新启动服务,服务会从中断的步骤继续执行。 场景举例:爬取某网站时,有时需要用户输入短信,此时需要人为参与,程序必须中断,等用户输入短信后才可以继续执行 代码示例: 中断代码
@Override public void afterCrawl(TransContext<TestRequest, TestResponse> context, HttpCrawlInfo crawlInfo, String crawlId, String mobileType) throws UncsException { // 中断一下 this.pauseNeedMsg(); System.out.println(crawlInfo.getHttpCrawlResult()); }
重新启动服务
// 重新启动服务 String msgCode = "; TestResponse response1 = UncsService.restartService(crawlId, msgCode, null, TestResponse.class);
六、代理配置及使用
uncs支持http代理和socks5代理,支持用户自定义代理获取方式,也支持使用系统提供的代理方式,强扩展性。 代理配置方式一:
<!-- 默认的http代理 --> <uncs:crawl id=" proxyType="default-http"> <!-- 默认的socks代理 --> <uncs:crawl id=" proxyType="default-socks"> <!-- 系统启动时,设置默认的两种代理方式及全局代理方式 InitParam param = , , , "no");-->
代理配置方式二:
<uncs:crawl id=" proxyType="http"> <uncs:list> <uncs:netCrawlPart class="com.cdc.uncs.service.parts.NetCrawlTestPart" desc="步骤"/> </uncs:list> <!-- 实现类必须继承对应的类 com.cdc.uncs.http.IHttpProxy或com.cdc.uncs.http.ISocksProxy --> <uncs:proxyService class="com.cdc.uncs.http.impl.TestHttpProxy"> <uncs:property name="ip" value="127.0.0.1"/> <uncs:property name="testxxxxx" value=""/> </uncs:proxyService> </uncs:crawl> package com.cdc.uncs.http.impl; import com.cdc.uncs.http.IHttpProxy; import com.cdc.uncs.http.ISocksProxy; import com.cdc.uncs.util.HttpGreenHelper; import org.apache.http.HttpHost; import java.util.HashMap; import java.util.Map; /** * 默认http代理 */ public class TestHttpProxy extends IHttpProxy { private String ip; private Object testxxxxx; public TestHttpProxy() { } /** * 获取crawlId * * @param cid 唯一标识 * @param type 类型 * @param logServerName 日志标识 * @return */ @Override public HttpHost getProxy(String cid, String type, String logServerName) { ); } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } public Object getTestxxxxx() { return testxxxxx; } public void setTestxxxxx(Object testxxxxx) { this.testxxxxx = testxxxxx; } }
代理配置方式三:可以在某个步骤单独使用代理,参考《四-4.2 netCrawlPart》
七、日志配置及使用
uncs使用固定日志名,分为标准日志和uncs日志,标准日志是日志搜索系统要求的格式输出,可以忽略,uncs日志表示业务日志 logback:
<property name="log.base" value="D:/log/uncslog" /> <appender name="uncslog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <fileNamePattern>${log.base}/uncs%d{yyyy-MM-dd}.log</fileNamePattern> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern> ${log.base}/uncs.log.%d{yyyy-MM-dd}.log </FileNamePattern> </rollingPolicy> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>[%level] %date [%thread] - %msg%n</pattern> </layout> </appender> <appender name="standardlog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <fileNamePattern>${log.base}/flow_standard%d{yyyy-MM-dd}.log</fileNamePattern> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern> ${log.base}/flow_standard%d{yyyy-MM-dd}.log </FileNamePattern> </rollingPolicy> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%date{"yyyy-MM-dd,HH:mm:ss,SSS"}||%msg%n</pattern> </layout> </appender> <!-- 标准日志 --> <logger name="standard" additivity="false"> <level value="DEBUG" /> <appender-ref ref="standardlog" /> </logger> <logger name="com.cdc.uncs" additivity="false"> <level value="DEBUG" /> <appender-ref ref="uncslog" /> </logger>
八、异步化
提供异步化服务
// 异步启动服务 UncsService.ayncStartService // 获取当前服务状态 UncsService.getResponse
九、未来猜想
优化代码质量,完善http初始化部分代码(优化完毕)及cookie处理部分代码(完成)
让part持有context,这样部分方法不再需要context参数(完成)
提供快速生成代码工具
提供可视化工具,随时查看某个crawlId对应的状态
集成各大优秀的爬虫框架,形成对应模板
提供单机模式,可以选择不使用redis,本地存储
提供并发步骤模板,用于提高速度(完成)
十、fiddler使用说明
升级版本到2.3.0.1-SNAPSHOT以上
vm参数-Duncs.useFidder=1
fiddler配置 tools->fiddler options->https->actions->export root certificate to ...
\bin\keytool.exe -import -file C:\Users\Desktop\FiddlerRoot.cer -keystore FiddlerKeystore -alias Fiddler
作者:刘鹏飞
来源:宜信技术学院
Java爬虫快速开发工具uncs的部署攻略的更多相关文章
- 【JAVA EE企业级开发四步走完全攻略】
本文是J2EE企业级开发四步走完全攻略索引,因内容比较广泛,涉及整个JAVA EE开发相关知识,这是一个长期的计划,单个发blog比较零散,所以整理此索引,决定以后每发一季JAVA EE blog后会 ...
- JAVA EE企业级开发四步走完全攻略 [转]
http://bbs.51cto.com/thread-550558-1.html 本文是J2EE企业级开发四步走完全攻略索引,因内容比较广泛,涉及整个JAVA EE开发相关知识,这是一个长期的计划, ...
- 开发者必知的8款App快速开发工具
开发者必知的8款App快速开发工具 “我有一个好创意,就差一个CTO……” “原生APP开发难度大,周期长,成本高,还没上线市场已经被占领了.” “APP版本迭代更新,都是企业的一道难关,没有一个一劳 ...
- 肝了一个半月的 Java 项目快速开发脚手架:Chewing
前言 闲来无事,整一个 Java 项目快速开发脚手架. 正文 一.简介 Chewing 是一个简单的 Java 项目快速开发脚手架.既适合需要开发小型项目的小伙伴使用,也适合刚入门的新手用来学习一些常 ...
- (转载)实例详解Android快速开发工具类总结
实例详解Android快速开发工具类总结 作者:LiJinlun 字体:[增加 减小] 类型:转载 时间:2016-01-24我要评论 这篇文章主要介绍了实例详解Android快速开发工具类总结的相关 ...
- 快速开发工具:Servoy
快速开发工具:Servoy https://servoy.com/
- java基础-Eclipse开发工具介绍
java基础-Eclipse开发工具介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 所谓工欲善其事必先利其器,即将身为一名Java开发工程师怎么能没有一款好使的IDE呢?今天就 ...
- java基础-Idea开发工具介绍
java基础-Idea开发工具介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 之前给大家介绍过一款Java的IDE叫eclipse,有些功能用起来不是很得心应手,尤其是在导报的 ...
- 开发者不可不知的五款DIY快速开发工具,你造吗
对于非专业的移动开发者,弱化编程能力的快发开发工具实用性够强,无需编程只要借助工具提供的各种功能模块,就能开发出属于自己的应用,而支持DIY更能使应用开发锦上添花,借助快速开发工具开发出属于自己的“能 ...
随机推荐
- HUST——1103Party(拓扑排序+个人见解)
1103: Party Time Limit: 2 Sec Memory Limit: 64 MB Submit: 11 Solved: 7 Description N students were ...
- mybatis读取oracle中blob
controller: byte[] blob = commonService.getPersonImage(bean.getIdCard()); String base64 = new String ...
- javascript中 for循环的一些写法 for length 以及for in 还有 for of 的区别
最近在写一些前端的代码,遇到一个产品列表遍历的问题,正好使用到for 的几种用法,于是研究了下. 代码如下,先说明下goodslist 是一个产品列表 形如这样的数据格式 { ‘types’:1, ' ...
- python:print含有中文的list
Python 的 List 如果有中文的话, 会印出 \xe4\xb8... 等等的编码(如下所示), 要如何印出中文呢? >>> a = ['中文', 'ab']>>& ...
- 【CF56E】Domino Principle(线性扫描,伪DP)
每块多米诺骨牌所在的位置设为x,每块多米诺骨牌高度为h.如果将x位置上的多米诺骨牌向右翻到,它就可以影响[x+1, x+h-1]范围内的所有多米诺骨牌,让他们也翻到,同时这些被翻到的多米诺骨牌还能影响 ...
- JQuery 入门学习附常用UI模块
一.简介 jQuery 库可以通过一行简单的标记被添加到网页中 jQuery 是一个 JavaScript 函数库. jQuery 库包含以下特性: HTML 元素选取 HTML 元素操作 CSS 操 ...
- 标准C程序设计七---120
Linux应用 编程深入 语言编程 标准C程序设计七---经典C11程序设计 以下内容为阅读: <标准C程序设计>(第7版) 作者 ...
- 深入了解Entity Framework框架及访问数据的几种方式
一.前言 1.Entity Framework概要 Entity Framework是微软以ADO.NET为基础所发展出来的对象关系映射(O/R Mapping)解决方案.该框架曾经为.NET Fra ...
- Codeforces 895E Eyes Closed(线段树)
题目链接 Eyes Closed 题意 两个人玩一个游戏,现在有两种操作: 1.两个人格子挑选一个区间,保证两个的区间不相交.在这两个区间里面各选出一个数,交换这两个数. 2.挑选一个区间,求这个 ...
- [Inside HotSpot] UseParallelGC和UseParallelOldGC的区别
JVM的很多参数命名很有迷惑性,-XX:+UseParallel,-XX:+UseParallelOldGC,-XX:+UseParNewGC,-XX:+UseConcMarkSweepGC咋一看容易 ...