机器学习之数据获取(Machine Learning about data)
一、爬虫自动化——爬虫基础Basic of Spider1、理论基础1.1 HTTPHTTPHyperText Transfer Protocol是用来定义客户端和服务端之间通行格式的协议。1. 先向浏览器发送url链接请求2.DNS 服务器将 url 链接解析成IP 地址3. 浏览器根据 IP 地址找到 url 对应的服务器发送一个HTTP 请求4. 服务器接收到 HTTP 请求处理请求后返回HTTP 响应5. 浏览器解析对应的 HTTP 响应显示对应的页面HTTP的核心请求-响应模型一问一答无状态无状态服务器不会记住先前做了什么1.2 URLURLUniform Resource Locator访问网页时输入的网址协议http | https主机名服务器的域名 或 IP端口http(80) | https(443)路径资源在服务器上的位置查询参数通常以 ? 开头多个参数使用 进行分隔锚点页面内定位1.3 HTTP请求HTTP请求主要包括了三大部分请求行、请求头、请求体。1.4 请求方法对比GET vs POST特性GETPOST参数位置URL查询参数?后请求体中数据大小受URL长度限制~2KB-8KB无限制安全性参数暴露在URL中参数在请求体中用途获取数据查询、浏览提交数据登录、上传缓存可被缓存通常不缓存幂等性幂等多次请求结果相同非幂等1.5 HTTP状态码爬虫里面常见的状态码200 OK请求成功301/302页面重定向304 Not Modified资源未修改使用缓存400 Bad Request请求格式错误401 Unauthorized需要登录认证403 Forbidden禁止访问网站在反爬404 Not Found页面不存在429 Too Many Requests请求太频繁被限流500/502/503/504服务器内部错误1.6 requests库requests 是 Python 里面最流行的 HTTP 客户端库能够快速构建 HTTP 请求进行发送给服务器。import requests headers { User-Agent:..., Accept:..., Cooike:... } resp requests.get(网址,headersheaders)resp.url查看实际发出的完整URL参数会自动拼接resp.status_code200成功4xx客户端错误5xx服务器错误resp.json()如果响应是JSON格式自动解析为Python字典2、XPath 与 CSS 选择器2.1 HTML 网页结构分析网页是一种由 HTMLHyperText Markup Language写的。HTML是一种标记语言用标签来描述网页的结构。HTML标签是层层嵌套的形成一棵树形结构叫做DOM树Document Object Model。爬虫本质就是从DOM树里面提取到我们需要的数据。2.2 XPath: 路径表达式XPath(XML Path Language)是一种在DOM树中定位节点的语言Python里面使用 lxml 库支持XPath。表达式含义示例//tag任意位置的标签//div 匹配所有 div/tag子元素/html/body/div//tag[attr]有指定属性的标签//div[class]//tag[attrvalue]属性等于指定值//div[classproduct]//tag/text()标签的文本//h2/text()//tag/href标签的属性//a/href//tag[1]第 1 个索引从 1 开始//div[1]//tag[last()]最后一个//div[last()].当前节点同级兄弟在已选中节点内继续查找..父节点获取父元素2.3 CSS 选择器CSS 选择器是 Web 前端常用的选择器Python 里面 BeautifulSoup 库支持 CSS 选择器。选择器含义示例.classclass 属性.product 匹配 classproduct#idid 属性#p1 匹配 idp1tag标签名div、a、span[attrvalue]属性筛选[href/detail]parent child直接子元素.list .itemancestor descendant后代元素空格.container .item:first-child第一个子元素li:first-child:nth-child(n)第 n 个子元素li:nth-child(2)3、正则表达式3.1 正则表达式用途验证检测字符串是否合格提取在文本里面找到需要验证的内容替换对找到的内容进行替换分隔用模式作为分隔符切分字符串3.2 正则函数import re函数作用返回值re.search(pattern, string)查找第一个匹配Match 对象或 Nonere.match(pattern, string)从字符串开头匹配Match 对象或 Nonere.findall(pattern, string)查找所有匹配字符串列表re.sub(pattern, replacement, string)替换所有匹配新字符串re.split(pattern, string)用模式分割字符串字符串列表re.compile(pattern)编译正则提高效率Pattern 对象区别search是从某个位置开始找到的第一个匹配match是从字符串开头找到的第一个匹配findall是找字符串里面全部匹配3.3 正则的原子原子匹配内容示例a字符 a 本身a 匹配 a\.转义的点匹配 .\. 匹配 .\d任意数字0–9\d 匹配 1、9、0\D非数字\D 匹配 a、汉\w字母、数字、下划线\w 匹配 a、1、_\W非字母数字下划线\W 匹配空格、、#\s空白字符空格、制表符、换行\s 匹配空格、\n、\t\S非空白字符\S 匹配 a、1、.任意字符除换行. 匹配 a、1、3.4 量词量词含义示例*0 次或多次a* 匹配空、a、aaa1 次或多次a 匹配 a、aaa不匹配空?0 次或 1 次a? 匹配 a 或空{n}恰好 n 次a{3} 匹配 aaa{n,}n 次或更多a{2,} 匹配 aa、aaa、aaaa{n,m}n 到 m 次a{2,4} 匹配 aa、aaa、aaaa3.5 贪婪 与 非贪婪text div内容1/divdiv内容2/div # 贪婪匹配默认.* 尽可能多地匹配 re.findall(rdiv.*/div, text) # → [div内容1/divdiv内容2/div]整段一起匹配 # 非贪婪匹配加 ?.*? 尽可能少地匹配 re.findall(rdiv.*?/div, text) # → [div内容1/div, div内容2/div]每个 div 单独匹配在处理HTML标签的时候 .* 是贪婪也是默认这时候提取常用到 .*? 非贪婪模式3.6 选择用 [] 定义字符类匹配其中任意一个字符表达式含义示例[abc]匹配 a、b、c 中的任意一个[aeiou] 匹配元音字母[^abc]匹配除了 a、b、c 的其他字符[^0-9] 匹配非数字[a-z]匹配 a 到 z[a-zA-Z] 匹配所有字母[0-9]匹配数字等价于 \d—3.7 分组括号 () 不仅用于分组还可以只提取匹配的部分text 订单#ORD001 金额¥5999 数量2 # 不分组提取整个匹配 re.findall(r订单#\w 金额¥\d, text) # → [订单#ORD001 金额¥5999] # 分组只提取括号内的部分 → 元组列表 re.findall(r订单#(\w) 金额¥(\d), text) # → [(ORD001, 5999)]