网页结构基础:
如果在一行网页源代码前看到一个三角箭头,就表明它是个大框,里面还嵌套着其他框,单击箭头就可以展开,看到里面嵌套的其他框。文本内容一般都在最小的框里
<! DOCTYPE html>与<html>是固定写法,作用是将代码声明为HTML文档
<meta charset='UTF-8'/>,meta标签指定了网页使用UTF-8字符
<body>框表示主体信息,是最终展示在网页上的内容。<body>框里的一些小框则是各种具体内容,之后将详细讲解。< >包围起来的内容就是标签,例如,<body>读作body标签。通常写完<body>之后,最后得写一个</body>,表示一个框的闭合
标题是通过<h1>~<h6>标签来定义的,一般格式为:<h1>标题内容</h1>。其中<h1>的字号最大,<h6>的字号最小
段落是通过<p>标签来定义的,一般格式为:<p>段落内容</p>
链接是通过<a>标签来定义的,一般格式为:<a href="链接地址">文本内容,target="_blank"表示单击链接后在新标签页中打开目标链接,img用于生成图片,src属性指定图片源文件的地址,可以使用相对路径调用本地图片,或者使用互联网上能访问到的图片链接。width和height属性分别指定图片的宽度和高度,单位是像素
区块最主要的表现形式就是<div>×××</div>格式,在每个<div>×××</div>分区下还可以继续用<div>×××</div>进行进一步分区。
h1至h6、p都是块级标签,而a、img则是内联标签。浏览器在渲染HTML页面时会遵循默认的文档流,从上往下依次显示每个HTML标签,对于块级标签则独占一行,对于内联标签则放置在同一行,直到总宽度超过浏览器宽度才换行。
<p>第一段<br/>第二段</p>,在HTML标签之间或者p等标签内容中添加br,用于添加空白行或换行
div和span分别属于块级标签和内联标签,都可以用作其他HTML标签或页面文本的容器。它们本身没有具体的语义,仅作为其他内容的容器
table属于块级标签,使用table标签可以定义表格,用tr表示表格中的每一行,用td表示每一行中的单元格,用th表示表头行中的单元格
ul和ol属于块级标签,使用ul和ol定义列表,分别对应无序列表和有序列表,用于展示多个并列项,每一项用li定义
网页结构进阶:
选择元素的基本方法www.python3.vipid属性可以给标签取一个id, id值应当在整个页面中独一无二,使用id可以有针对性地操作某一个标签
同一个class值可以应用于多个标签,如果说class(类)是为了划分类别,那么id则是为了更加严格地区分不同的元素。打个比方来说,class相当于人的性别(男性和女性), id则相当于人的身份证号码
name属性和class类似,只是基于name控制相应的标签没有class那么方便,可以将id、class和name理解成一个人的身份证号、姓、名等
style属性可以为标签添加内联样式
表单标签一般都会放在form标签中,使得在触发提交时,可以一并上传全部表单标签的值
display属性可以决定DOM元素的显示方式,可以设置为inline、block、inline-block等,分别对应内联元素、块级元素、内联块级元素
多窗口实战,current_window_handle用来获取当前浏览器的窗口句柄,window_handles用来获取浏览器的所有窗口句柄
下拉框定位的思路
索引定位select_by_index,value定位select_by_value,文本定位select_by_visible_text
正则表达式:
大部分情况下需要用到的只有(.*? )与.*?,“.*”称为贪婪匹配,会匹配到过多的内容。如果再加上一个“? ”构成“.*? ”,就变成了非贪婪匹配,修饰符有很多,最常用的是re.S,其作用是在使用findall()查找时,可以自动考虑到换行的影响,使得.*?可以匹配换行
import
(.*? )用于获取文本A与文本B之间的内容,并不需要知道它的确切长度及格式
文本
sub()函数中的sub是英文substitute(替换)的缩写,以下2种方法都可以完成替换
中括号最主要的功能是使中括号里的内容不再有特殊含义。在正则表达式里,“.”“*”“? ”等符号都有特殊的含义,但是如果想定位的就是这些符号,就需要使用中括号
-------------------------------------实战----------------------------------
提取百度新闻标题、网址、日期及来源
批量获取多家公司的百度新闻并生成数据报告
通过Python生成一个文本文件
完整代码
间断运行与异常处理
如果需要进行批量爬取,最好先对网址是否支持中文进行测试。如果测试结果是不支持中文,比较简单的解决办法,是在原来的网址末尾加上“&ie=utf-8”,这样就算前面输入的是中文,对网址也没有影响
总结一下网络数据挖掘的思路:
第一步:获取网页源代码;
第二步:通过正则表达式提取想要的内容;
第三步:数据清洗;
第四步:定义函数并通过循环调用函数进行批量爬取
将数据挖掘爬取到的数据存入数据库
数据去重
据清洗的常见手段:strip,split,sub
以“2019-01-14”的格式作为统一的标准。那么对于“2019-01-14 18:28”这样的日期格式,可以利用split()函数来截取前半部分;对于“2019年01月14日”这样的日期格式,可以利用sub()函数将“年”“月”替换为“-”号,将“日”替换为空字符,即删除;对于“4小时前”“58分钟前”这样的日期格式,处理方法也不复杂,只要把包含“小时”或“分钟”的日期都统一替换为今天的日期即可。具体代码如下:
例如,筛选下面两条新闻正文内容时,如果将公司名称设置为“华能信托”,那么第二条新闻就不符合判断标准,会被删除;而如果将公司名称设置为“华能贵诚信托”,则会导致第一条新闻被删除。然而“华能信托”和“华能贵诚信托”指的是同一家公司,前者为简称,后者为全称,所以这两条新闻都是我们需要的。那么有没有什么好的解决办法呢?
上述第1行代码中用了一个正则表达式,其中company_re是匹配规则,company[0]表示公司名称的第一个字,company[-1]表示公司名称的最后一个字,“.{0,5}”是个新知识点,“.”表示任意一个字符,“.{0,5}”则表示0~5个任意字符(这里的逗号后一定不能有空格),所以company_re就是用来匹配“公司名称第一个字+0~5个任意字符+公司名称最后一个字”这样的字符串。如果公司名称较长,可以根据实际需要将5修改为稍大的数字。
通过re.findall(company_re, article)寻找满足匹配规则company_re的内容。如果能找到相关内容,则通过findall()获得的列表长度就大于1;如果没找到相关内容,则列表长度小于1,就可以执行将该新闻赋值为空值然后清除的操作了。