1.基础部分
1.1环境搭建
- 一个开源的Python发行版本Anaconda
- https://www.anaconda.com
- 64-Bit Graphical Installer (435 MB)
- 64-Bit Command Line Installer (428 MB)
- 清华镜像https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/
- IDE:VS code
- https://code.visualstudio.com
- 安装Open HTML in Default Browser插件
- 运行代码Run Python file in Terminal
- mac终端命令行
输入命令conda list 列出所有安装的工具包。比如 lxml pip requests
- 安装后系统默认使用Anconda的python环境
输入命令python -V可正常查看版本信息
- 虚拟机的概念(用Hypervisor技术虚拟硬件来限制每个应用消耗的最大资源,防止整个系统崩溃)
Linux 命令
//删除文件夹
rm -f files/
//删除文件
pwd
//查看目录路径
mv project/spider.py ./
//移动spider.py目录到当前目录
find . -name spider.py
//全局查找命名为spider.py的文件
find ./text/ -name spider.py
//text目录查找命名为spider.py的文件
ps
//查看进程
ps aux
//所有进程
ps aux | grep visual
//查询名称为visual的进程
kill
//杀进程
grep
//搜索关键字文本
netstat
//端口占用
top
//cpu进程
1.2HTML 基础
常见的标签属性 id,name,class
document.getElementsByName
document.getElementsByClassName
document.getElementsByTagName
1.3内容抽取及解析
requests.get(url,headers=headers) 获取链接
requests.get(url).text 返回该链接下解码过的文本
requests.get(url).content 返回该链接下原始字节流
1.4编码/解码
UTF-8 1-7可变长的编码方式
Unicode 2字节定长的编码方式
binary stream 二进制字节流
UTF-8 -> encode -> Unicode
Unicode -> decode -> UTF-8
Python 2.7 默认 UTF8
‘你好’ -> b’\xe4\xbd\xa0\xe5\xa5\xbd’
‘你好’.decode(‘utf8′) -> u’\u4f60\u597d’
Python 3.6 默认Unicode
‘你好’.encode(‘utf8′) -> b’\xe4\xbd\xa0\xe5\xa5\xbd’
1.4存储
r<读文件
w写文件
b二进制的方式打开
b在文件结尾继续添加的方式写入,区别:w默认为覆盖
+每种操作的一种扩展模式,含义各不同,比如 r+ w+
如果没有改文件w+ 能创建一个新文件
url = "http://baidu.com" resp = requests.get(url) f = open('url','w') f.write(resp.text) f.close() //以字符串形式写入
filename = url[url.rfind('/')+1:] f = open(filename, 'w') f.write(resp.text) f.close() //存储url
MD5函数
hashlib.md5(url.encode('utf8')).hexdigest()
上下文管理器
import re s = "Total income is around $750,000, ended with 3000." re.findall('[\d,]+', s) //匹配数字返回 re.findall('\$([\d,]+),\s', s) //匹配$符号开头,,空格结束的数字
2.解析
2.1网站结构分析
正则表达式
^ 字符串起始
$ 字符串结束
* 匹配前面表达式0次或多次
+ 匹配前面表达式1次或多次
? 匹配前面表达式0次或1次
{n,m} 匹配前面表达式最少n次,最大m次
. 匹配除了换行符以外的所有符号
s3 = '< href="http://www.baidu.com">Baidu</>' re.findall('href=\"(.*)\"',s3)
//抓取a标签里的链接地址(重复匹配href=“开头”结束的字符并且返回)
()内是需要匹配的结果,其他是过滤条件
re.findall('[a-z]+',s)
[]表示满足条件的字符集合
re.findall('[^0-9]+',s)
[]里的^表示取非
贪婪模式
re.findall('href=\".*>',s3)
->[‘href=”http://www.baidu.com”>Baidu</a>’]
非贪婪模式
re.findall('href=\".*?>',s3)
->[‘href=”http://www.baidu.com”>’]
sub替换模式
re.sub('(?<=>)(.*?)(?=<)','Taobao',s3)
(?<=pattern) sub (?=pattern) 替换的时候保留前后匹配条件
'<a href="http://www.baidu.com">Taobao</a>'
compile预编译
pattern = re.compile('>.*?<')
所有的性能优化无外乎空间换时间,时间换空间
pattern.search(s3)
匹配一次
pattern.refindall(s3)
匹配多次
DOM操作器XPATH
nodename:选取此节点的所有字节点, tag或*选择任意tag
/:从根节点选取,选择直接字节点,不包含更小的后代(例如孙、从孙)
//:包含所有后代
. :选取当前节点
.. :选取当前节点的父节点
@ :选取属性
第一个段落
</div>
<div class="main-content">
你要爬取的内容
</div>
python3 //进入python
from lxml import etree
resp = re.sub('\n','',open('spider.py','r').read()) //读入上面的html代码,去除空格
tree = etree.HTML(resp)//获取html dom树
tree.xpath('/html/body/div[2]/p')[0].text //利用xpath操作器获取p标签下面的内容
>>> ' 你要爬取的内容 '
xpath的下标不是从0开始,而是1. div[2]表示第二个div标签
[, , ]
xpath返回的均为数组,需要得到某个元素需要配合使用下标
tree.xpath('//p|//h1')
tree.xpath('//*[self::p or self::h1]')
tree.xpath('//*[@class="surface--content" or class="main-content")