整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Python学习笔记(11)Web页面元素提取

Python学习笔记(11)Web页面元素提取

eb页面, 一般是HTML页面,是Internet组织 信息的基础元素。Web页面元素提取是一类常见 问题,在网络爬虫、浏览器等程序中有着不可或 缺的重要作用。

HTML指超文本标记语言,严格来说,HTML不 是一种编程语言,而是一种对信息的标记语言, 对Web的内容、格式进行描述。

自动地从一个链接获取HTML页面是简单网络爬虫的功能,可以整体分成如下4个步骤:

  1. 步骤1: 读取保存在本地的html文件;
  2. 步骤2:解析并提取其中的图片链接;
  3. 步骤3:输出提取结果到屏幕;
  4. 步骤4:保存提取结果为文件。

根据上述步骤,可以写出主程序如下。其中设置 了4个函数getHTMLlines()、extractImageUrls()、 showResults()和saveResults()分别对应上述4个步骤。

getHTMLlines():读取保存在本地的html文件

extractImageUrls():解析并提取其中的图片链接

showResults():输出提取结果到屏幕

saveResults():保存提取结果为文件

代码:

def main(): 
 inputfile='nationalgeographic.html' 
 outputfile='nationalgeographic-urls.txt' 
 htmlLines=getHTMLlines(inputfile) 
 imageUrls=extractImageUrls(htmlLines) 
 showResults(imageUrls) 
 saveResults(outputfile, imageUrls)

定义main()函数的目的是为了让代码更加清晰, 作为主程序,也可以不采用函数形式而直接编写。 main()前两行分别制定了拟获取HTML文件的路 径和结果输出路径。

getHTMLlines():读取保存在本地的html文件

getHTMLlines()函数读取HTML文件并内容, 并将结果转换为一个分行列表,为了兼容不同编 码,建议在open()函数中增加encoding字段,设置采用UTF-8编码打开文件。

def getHTMLlines(htmlpath): 
 f=open(htmlpath, "r", encoding='utf-8')
 ls=f.readlines() 
 f.close() 
 return ls

extractImageUrls():解析并提取其中的图片链接

extractImageUrls()是程序的核心,用于解析文件并提取图像的URL。

def extractImageUrls(htmllist): 
 urls=[] 
 for line in htmllist: 
 if 'img' in line: 
 url=line.split('src=')[-1].split('"')[1] 
 if 'http' in url: 
 urls.append(url) 
 return urls

showResults():输出提取结果到屏幕

showResults()函数将获取的链接输出到屏幕上,增加一 个计数变量提供更好用户体验。

def showResults(urls): 
 count=0 
 for url in urls: 
 print('第{:2}个URL:{}'.format(count, url)) 
 count +=1

saveResults():保存结果到文件

在 HTML 文档中 <input type="file"> 标签每出现一次,一个 FileUpload 对象就会被创建。

该元素包含一个文本输入字段,用来输入文件名,还有一个按钮,用来打开文件选择对话框以便图形化选择文件。

该元素的 value 属性保存了用户指定的文件的名称,但是当包含一个 file-upload 元素的表单被提交的时候,浏览器会向服务器发送选中的文件的内容而不仅仅是发送文件名。

当用户选择或编辑一个文件名,file-upload 元素触发 onchange 事件句柄。

看个简单例子:

[html]view plaincopy

<!--?oscar999??-->??
<!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN">??
<html>??
??<head>??
??<meta?http-equiv="content-type"?content="text/html;?charset=utf-8">??
??<meta?name="author"?content="oscar999">??
??<title></title>??
??<script>??
??function??handleFiles(files)??
??{??
????if(files.length)??
????{??
???????var?file?=?files[0];??
???????var?reader?=?new?FileReader();??
???????reader.onload?=?function()??
???????{??
???????????document.getElementById("filecontent").innerHTML?=?this.result;??
???????};??
???????reader.readAsText(file);??
????}??
??}??
??</script>??
??</head>??
??<body>??
??<input?type="file"?id="file"?onchange="handleFiles(this.files)"/>??
??<div?id="filecontent"></div>??
??</body>??
</html>??

这里读取一个文件, 显示在div 中。

(在IE8 中 无效, this.files 无法读取文件。这个属于HTML5 的特性)

当选择了一个文件时,就会把包含这个文件的列表(一个FileList对象)作为参数传给handleFiles()函数了。这个FileList对象类似一个数组,可以知道文件的数目,而它的元素就是File对象了。从这个File对象可以获取name、size、lastModifiedDate和type等属性。把这个File对象传给FileReader对象的读取方法,就能读取文件了。



HTML5 Drag and Drop File

Html5 支持的File 的操作不仅仅是文件的选择,

在HTML5 之前需要使用 Applet 和 SilverLight 才能达到的文件拖拽功能,在HTML5 中也能轻松的实现,

看代码:

[html]view plaincopy

<!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN">??
<html>??
??<head>??
??<meta?http-equiv="content-type"?content="text/html;?charset=utf-8">??
??<meta?name="author"?content="oscar999">??
??<title></title>??
??</head>??
??<body>??
????<div?id="dropbox">?Drop?Here?</div>??
????<div?id="filecontent"></div>??
????<script>??
??????var?dropbox?=?document.getElementById("dropbox");????
??????dropbox.addEventListener("dragenter",?dragenter,?false);????
??????dropbox.addEventListener("dragover",?dragover,?false);????
??????dropbox.addEventListener("drop",?drop,?false);?????
????function?dragenter(e)?{????
????????e.stopPropagation();????
????????e.preventDefault();????
????}????
????function?dragover(e)?{????
????????e.stopPropagation();????
????????e.preventDefault();????
????}??
????function?drop(e)?{????
????????e.stopPropagation();????
????????e.preventDefault();?????
????????var?dt?=?e.dataTransfer;????
????????var?files?=?dt.files;??
????????if(files.length)??
????????{??
???????????var?file?=?files[0];??
???????????var?reader?=?new?FileReader();??
???????????reader.onload?=?function()??
???????????{??
???????????????document.getElementById("filecontent").innerHTML?=?this.result;??
???????????};??
???????????reader.readAsText(file);??
????????}??
????}???
????</script>??
??</body>??
</html>??

这里通过事件对象的 dataTransfer 可以得到文件。



读取文件内容

在第一个例子中, 我们使用 FileReader类来读取文件的内容,

在 W3C 草案中,File 对象只包含文件名,文件类型等只读属性;FileReader用于内容读取和监控读取状态。

(在firefox 中, 可以直接使用 var fileBinary=file.getAsBinary(); 读取文件的二进制源码)

FileReader提供的方法包括:

1. readAsBinaryString

2. readAsDataURL

3. readAsText

4. abort

.........


以下,举一个 使用 FileReader 将用户选择的图片不通过后台即时显示出来的例子。

[html]view plaincopy

function?handleFiles(files){??
????for?(var?i?=?0;?i?<?files.length;?i++)?{??
????????var?file?=?files[i];??
????????var?imageType?=?/image.*/;??
????????if?(!file.type.match(imageType))?{??
????????????continue;??
????????}??
????????var?img?=?document.createElement("img");??
????????img.classList.add("obj");??
????????img.file?=?file;??
????????preview.appendChild(img);??
????????var?reader?=?new?FileReader();??
????????reader.onload?=?(function(aImg){??
????????????return?function(e){??
????????????????aImg.src?=?e.target.result;??
????????????};??
????????})(img);??
????????reader.readAsDataURL(file);??
????}??
}??



同后端的交互

在一般的HTML 中,使用方式是把file input 放在form 中, 以POST 方式把文件传递到后端。

在 HTML5 中, 也可以通过 FileReader 的 readAsBinaryString 方法读取到文件的二进制码,然后通过 XMLHttpRequest 的 sendAsBinary 方法将其发送出去。

[javascript]view plaincopy

var?xhr?=?new?XMLHttpRequest();??
xhr.open("POST",?"url");??
xhr.overrideMimeType('text/plain;?charset=x-user-defined-binary');??
<pre?code_snippet_id="422893"?snippet_file_name="blog_20140709_4_2106578"?class="sh_javascript?sh_sourceCode"?name="code">xhr<span?class="sh_symbol">.</span><span?class="sh_function">sendAsBinary</span><span?class="sh_symbol">(</span>binaryString<span?class="sh_symbol">);</span></pre><br> ?

大家分享一个FileInput的使用实例,也是自己开发中遇到的问题

如何使用FileInput

使用时的样式

使用FileInput只需要将相关的js,css下载引用即可,相信当大家遇到这个问题的时候已经有了bootstrap开发的知识,这些基础已经不成问题

选择文件后的样式,如果配置妥当的话,点击上传按钮进度条将会读满并显示Done

前台代码,这里有一个小小的问题 form表单的enctype属性

表单中enctype="multipart/form-data"的意思,是设置表单的MIME编码。默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;只有使用了multipart/form-data,才能完整的传递文件数据,进行下面的操作.
但是我们不需要配置,否则会出现form表单提交其他数据的问题

[html] view plain copy

  1. <div class="line line-dashed line-lg pull-in"></div>
  2. <div class="form-group">
  3. <label class="col-sm-3 control-label">照片</label>
  4. <div class="col-sm-9">
  5. <input id="JSh_ZhP" type="file" class="file" name="file">
  6. <input type="hidden" id="JSh_ZhP_Path" name="tbllecturer.JSh_ZhP"/>
  7. <p class="help-block">支持jpg、jpeg、png、gif格式,大小不超过2.0M</p>
  8. </div>

接下来就说说如何配置相应的js

默认的fileinput.js应该有一个页面加载完毕的动作,我们打开fileinput.js,果然有相应的方法。

[javascript] view plain copy

  1. $(document).ready(function () {
  2. var $input=$('input.file[type=file]');
  3. if ($input.length) {
  4. $input.fileinput();
  5. }<span style="font-family:Arial, Helvetica, sans-serif;"> });</span>

接下来将它注释掉,我们自己写初始化方法,在fileinput,js里添加initFileInput方法,并自己完成加载时的方法,文件上传的一般逻辑应该是点击文件上传,将文件在后台做相应的处理后将存储的Url返回添加到form表单中,跟随form表单一起提交到数据库中。.on()方法为fileInput上传文件后的回调方法,之后对返回的数据处理即可。

[javascript] view plain copy

  1. function initFileInput(ctrlName,uploadUrl) {
  2. var control=$('#' + ctrlName);
  3. control.fileinput({
  4. language: 'zh', //设置语言
  5. uploadUrl: uploadUrl,
  6. showUpload: true, //是否显示上传按钮
  7. showRemove:true,
  8. showPreview : true,
  9. dropZoneEnabled: false,
  10. showCaption: true,//是否显示标题
  11. allowedPreviewTypes: ['image'],
  12. allowedFileTypes: ['image'],
  13. allowedFileExtensions: ['jpg', 'png', 'gif'],
  14. maxFileSize : 2000,
  15. maxFileCount: 1,
  16. //initialPreview: [
  17. //预览图片的设置
  18. // "<img src='http://127.0.0.1:8080/NewsManageSys/plugin/umeditor1_2_2/jsp/upload/20161030/55061 477813913474.jpg' class='file-preview-image' alt='肖像图片' title='肖像图片'>",
  19. //],
  20. }) }
  21. $(document).ready(function () {
  22. var path=rootPath + "/lecturer/picture/upLoad.shtml";
  23. initFileInput("JSh_ZhP",path);
  24. $("#JSh_ZhP").on("fileuploaded", function (event, data, previewId, index) {
  25. $("#JSh_ZhP_Path").val(data.response);
  26. });
  27. });

后台处理的代码,我直接将文件存在了本地并将路径返回。

[java] view plain copy

  1. @ResponseBody
  2. @RequestMapping("picture/upLoad")
  3. public String upLoad(@RequestParam("file")CommonsMultipartFile file)
  4. throws Exception{
  5. String path="E:/images/"+new Date().getTime()+file.getOriginalFilename();
  6. File newFile=new File(path);
  7. file.transferTo(newFile);
  8. Map<String, String> map=new HashMap<String, String>();
  9. map.put("pathUrl", path);
  10. JSONArray json=JSONArray.fromObject(map);
  11. return path;
  12. }

到这里大家应该学会了fileinput的使用,如有问题请留言