python爬虫
计算机网络
IP
用32位二进制表示,记录时每八位转化为一个十进制数:xxx.xxx.xxx.xxx
局域网IP
动态IP:回收
静态IP:购买服务器
URL
1 | http://www.xxx.com:80/path/index.html?value1=1&value2=2#maodian |
- 协议:http, https, file, ftp;
- 域名或IP
- 端口:默认80;
- 路径
- 参数:通过问号直接拼接在URL,多个参数用
&
连接; - 锚点:锚点链接是超链接中的一种,可以使用它链接到文档中的某个特定位置。
网络协议
- 应用层:http, ftp, pop3, DNS;应用程序;
- 表示层:
- 会话层:
- 传输层:TCP, UDP;
- 网络层:IP, ICMP, IGMP;路由器;
- 数据链路层:ARP, RARP;交换机;
- 物理层:物理传输介质;双绞线/集线器;
TCP/IP协议
- IP地址:是逻辑地址,可以变化;
- TCP(传输控制协议):负责把需要传输的数据分解成一定长度的片段;
是一种字节流,会处理IP层即以下的丢包、重复以及错误问题。
TCP提供了一种可靠、面向连接、字节流、传输层的服务,采用3次握手建立一个连接,4次挥手来关闭一个连接。 - IP协议:负责将数据片段贴上标签成为数据包,标签包括源IP地址和目标IP地址,决定数据传输的路径;
- 路由器:会根据数据包的地址信息查询路由表,然后以最佳路径发送数据包,不会确保数据的完整性。
socket编程
套接字
1 | import socket |
Q:由于目标计算机积极拒绝,无法连接。
A:换个端口试试。可能是被防火墙屏蔽了。
Q:[WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试。
A:再换个端口,可能是被占用了。:cry:
Q:过段时间发现突然连不上了
A:你可能换了个WiFi,IP地址变了:cry:
多线程
实现多个客户端与服务端的交互
1 | import threading |
HTTP协议
超文本传输协议,应用层协议。
特点:
- 是单向的,只有客户端发送了请求才会有服务器响应;
- 是纯文本协议,我们只需要传递纯文本就可以,web服务器会根据约定好的方法生成对应的HTTP信息;
- 通过指定
content-type
可以传递任意类型的数据对象; - 无连接-每次连接处理一个请求然后断开连接
- 无状态-没有记忆能力,需要cookie和session来区别
1 | 请求方法 URL 协议版本 //请求行 |
Q:通过python-socket写一个http响应,传送到浏览器却一直无响应,一直转圈圈;
A:不知道怎么就好了,,可能是响应写错了?\r\n表示换行
前端基础
html,css,JavaScript
浏览器的加载过程:
- 构建dom树;
- 子资源加载——加载外部的css,js,图片等;
- 样式渲染——css执行
dom树
ajax,json,xml
get,post
content-type:
- application/x-www-form-urlencoded
- multipart/form-data
- application/json
爬虫技术
爬虫数据采集分类
- 按照采集对象分类
- 全网采集(搜索引擎)
- 全站采集
- 具体网站的指定数据(目的明确)
- 采集方案分类
- 利用http协议采集-页面分析
- 利用API接口采集-APP数据采集
- 利用目标网站的API采集(开放的):github,微博
request
方法
1 | import requests |
状态码
- 1*:信息,服务器收到请求,需要请求者继续执行操作;
- 2*:200,201等,成功,操作被成功接收并处理;
- 3*:301,302等,重定向,需要进一步的操作以完成请求;
- 4*:401,404,400,403等,客户端错误,请求包含语法错误或无法完成请求;
- 5*:500,501,502等,服务端错误,服务器在请求的过程中发生了错误。
正则表达式
基本语法
符号 | 作用 |
---|---|
. | 匹配任意字符(不包括换行符) |
^ | 匹配开始位置 |
$ | 匹配结束位置 |
* | 匹配前一个元字符0到多次(匹配最长长度) |
+ | 匹配前一个元字符1到多次 |
? | 匹配前一个元字符0到1次 |
{m,n} | 匹配前一个元字符m到n次 |
\\ |
转义字符 |
[ ] | 字符集,可匹配其中任意一个字符 []中的短横线-表示区间,所以想表示一个字符时要放在末尾 |
| | 或 |
\b |
匹配位于单词开始或结束位置的空字符串(可以自行判断是否是一个单词) |
\B |
匹配不位于单词开始或结束位置的空字符串 |
\d |
匹配一个数字=[0-9] |
\D |
匹配非数字 |
\s |
匹配任意空白字符=[ \t\n\r\f\v] |
\S |
匹配任意非空白字符 |
\w |
匹配数字、字母、下划线中任意一个字符=[a-zA-Z0-9_] |
\W |
匹配非数字、字母、下划线中任意字符 |
re
编译:re.compile("正则语法")
返回pattern对象,可供findall和match使用。
提取字符串
1 | import re |
match:正则语法中用小括号表示分组,匹配结果的对象自带group方法。
替换
1 | re.sub("正则语法","new","参数") |
模式
1 | re.IGNORECASE #忽略大小写 |
beautifulsoup4
1 | from bs4 import BeautifulSoup |
解析器
html.parser
√lxml
lxml-xml
xml
html5lib
定位方法
标签:
bs.标签名
find
bs.find("标签名") bs.find(id=" ") bs.find("标签名",id=' ') bs.find("标签名",{"class":"类名"}) bs.find("标签名",id=re.compile("正则表达式"))
1
2
3
4
5
6
7
- ```python
result = bs.find_all("标签名")
for tag in result:
#循环体
节点获取
子节点
1
2
3
4children = result.contents #子元素
children = result.descendants #所有子元素,包括子元素的子元素
for child in chhildren:
pass父节点
1
2
3
4parent = result.parent #返回单个父元素
parents = result.parents #返回所有父元素
for parent in parents:
pass兄弟节点
1
2
3
4next_siblings = result.next_siblings #返回目标之后的同等级节点内容
previous_siblings = result.previous_siblings #返回目标之前的同等级节点内容
for sibling in next_siblings:
pass
属性获取
1 | # 以class属性为例 |
XPATH
scrapy安装
官方安装文档:https://www.osgeo.cn/scrapy/intro/install.html#intro-install
第三方库的地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/
lxml
1
2pip install lxml
pip install 对应的whl文件 #在上述网址中去找lxmlwhl文件的下载一定要注意版本问题:https://blog.csdn.net/loopwastemytime/article/details/79919865
若想本地的库在pycharm的项目能使用,在项目\venv\pyvenv.cfg文件中,将include-system-site-packages的值修改为
true
twisted:与lxml的whl文件下载安装类似
XPATH简介
对象:xml&html
节点关系:
- 父节点
- 子节点
- 同胞节点
- 先辈节点
XPATH语法
符号介绍:
符号 | 说明 |
---|---|
/ | 从根节点选取,使用绝对路径,路径必须完全匹配 |
// | 从整个文档中选取,使用相对路径 |
. | 从当前节点开始选取 |
… | 从当前节点父节点开始选取 |
@ | 选取属性 |
例子:
表达式 | 说明 |
---|---|
article | 选取所有article元素的所有子节点 |
/article | 选取根元素article |
article/div | 选取所有属于article的子元素的div元素 |
//div | 选取所有div子元素 |
article//div | 选取所有属于article元素的后代的div元素 |
//@class | 选取所有名为class的属性 |
/article/div[1] | 选取属于article的子元素的第一个div元素 |
/article/div[last()] | 选取属于article的子元素的最后一个div元素 |
//div[@class] | 选取所有拥有class属性的div元素 |
//div[@class=’name’] | 选取所有class属性值为name的div元素 |
/div/* | 选取属于div元素的所有子节点 |
//* | 选取所有元素 |
//div[@*] | 选取所有带属性的div元素 |
//div/a|//div/p | 选取所有div元素的a和p元素 |
//span|//ul | 选取文档中的span和ul元素 |
article/div/p|//span | 选取所有属于article元素的div元素的p元素,和所有的span元素 |
插播一条血的教训:一定注意文件名称,不要与python的包名重复!
1 | from scrapy import Selector |
项目实战
- github地址:https://github.com/Alfred1984/interesting-python/tree/master/Weibo_Comment_Pics
相关微信文章:https://mp.weixin.qq.com/s/iTtVXMVdoTBxWHzEzbQH1Q
断更,做不出来。 - https://www.cnblogs.com/dhsfdhfhgufdu/p/15108793.html
每天一个放弃小技巧- 遇到百度安全验证,把请求头header带上
- 想要的内容被隐藏了,标签内容为空,源代码找不到,但是页面审查可以找到。