玩Python爬虫的必备知识清单
于2020-4-26重构
可以指明学习路线与方向
文章目录
- 玩Python爬虫的必备知识清单
- 你需要知道的基本概念
- 你需要掌握的库
- 你需要掌握的数据解析
- 你需要掌握的数据存储
你需要知道的基本概念
通用爬虫:百度、谷歌搜索引擎
聚焦爬虫:根据特定需求,从特定网站爬取特定数据
爬虫工具:pycharm+anaconda+google chrome(其他浏览器也行)
http协议: 超文本传输协议, 是一种发布和接收HTML页面的方法
https协议:是http协议的加密版本,在http下加入了SSL层。服务器端口号是443
端口
与浏览器交互过程:浏览器—>输入url-----get/post请求----->http服务器---->网站服务器----返回html---->http服务器---->用户浏览器【浏览器追加请求html引用的css、js、等动态文件】—…--->显示给用户
url:在浏览器中请求一个url
,浏览器会对这个url进行一个编码。除英文字母,数字和部分符号外,其他的全部使用百分号+十六进制码值进行编码
get请求: 只从服务器获取数据
post: 向服务器发送数据(登录)、上传文件等,会对服务器资源产生影响
爬虫时有反爬机制即强制要求用某种请求,具体爬虫时用哪种请求根据情况而定
谷歌抓包:
你需要掌握的库
urllib
基本介绍
最基本的网络请求库。可以模拟浏览器的行为,向指定的服务器发送一个请求,并可以保存服务器返回的数据,在Python3
的urllib
库中,所有和网络请求相关的方法,都被集到urllib.request库上
urlopen函数
resp = request.urlopen('http://www.baidu.com')
print(resp.read())
返回值
http.client.HTTPResponse 对象,故此用response做接收
urlretrieve函数
from urllib import request request.urlretrieve('http://www.baidu.com/','baidu1.html')
urlencode函数
from urllib import parse
data = {'name':'爬虫基础','greet':'hello world','age':100}
qs = parse.urlencode(data)
print(qs)
parse_qs函数
from urllib import parse
qs = "name=%E7%88%AC%E8%99%AB%E5%9F%BA%E7%A1%80&greet=hello+world&age=100"
print(parse.parse_qs(qs))//解码经过编码的url
{‘name’: [‘爬虫基础’], ‘greet’: [‘hello world’], ‘age’: [‘100’]}
request.Request类
反反爬必备伪装技术
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'
}
req = request.Request("http://www.baidu.com/",headers=headers)
resp = request.urlopen(req)
print(resp.read())
ProxyHandler处理器(代理设置)
为何使用:
固定某IP在某段时间内对网站服务器访问过多会被判定为非法访问,从而被限制或直接封掉
opener与handler
如需使用代理ip,则替代urlopen方法,使用如下系列操作方法
handler = request.ProxyHandler({"http":"218.66.161.88:31769"})opener = request.build_opener(handler)
req = request.Request("http://httpbin.org/ip")
resp = opener.open(req)
print(resp.read())
寻找可用的ip:西刺代理,快代理,或代理云 + ip检测工具(匹配可用id)
request
此库重写urllib的大多方法,比之前的常规方法做了更进一步封装,并且做了拓展
发送Get请求+
import requests
response = requests.get("http://www.baidu.com/")
import requestskw = {'wd':'中国'}headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
response = requests.get("http://www.baidu.com/s", params = kw, headers = headers)
print(response.text)
print(response.encoding)
发送POST请求
response = requests.post("http://www.baidu.com/",data=data)
import requestsdata = {'first': 'true','pn': 1,'kd': 'python'
}resp = requests.post(url,headers=headers,data=data)
print(resp.json())
代理设置
在请求的方法中(例如get
或者post
)传递proxies
参数就可以了
import requestsurl = "http://httpbin.org/get"headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
}proxy = {'http': '171.14.209.180:27829'
}resp = requests.get(url,headers=headers,proxies=proxy)
with open('xx.html','w',encoding='utf-8') as fp:fp.write(resp.text)
共享曲奇饼(COOKIE)
如果使用requests
,要达到共享COOKIE
的目的,那么可以使用requests
库给我们提供的session
对象。以登录人人网为例,使用requests
来实现。示例代码如下:
import requestsurl = "http://www.renren.com/PLogin.do"
data = {"email":"email@qq.com",'password':"pythonspider"}
headers = {'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"
}
session = requests.session()
session.post(url,data=data,headers=headers)
resp = session.get('http://www.renren.com/880151247/profile')print(resp.text)
你需要掌握的数据解析
在从目标网站获得我们像要的数据后,我们需要从全站html中提取我们像要的数据,提取工具有(任选一种)
- XPath+lxml库(√)
- 美丽汤4(beautifulsoup4)
- 正则表达式(√)
xpath
xpath(XML路径语言)是一门在XML和HTML文档中查找信息的语言,可用于XML和HTML文档中对元素和属性进行遍历。
你应该知道的节点关系
<bookstore><book><title>Harry Pottertitle><author>J K. Rowlingauthor><year>2005year><price>29.99price>
book>bookstore>
以上&#xff0c;book为父&#xff0c;其中4个为子&#xff0c;4个互为同胞&#xff0c;bookstore为其中所有元素的先辈
同理bookstore其中所有元素又为其后代元素
例子
<bookstore><book><title lang&#61;"eng">Harry Pottertitle> <price>29.99price>book><book> <title lang&#61;"eng">Learning XMLtitle> <price>39.95price>book>bookstore> bookstore>
XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。 下面列出了最有用的路径表达式&#xff1a;
表达式 | 描述 |
---|
nodename | 选取此节点的所有子节点。 |
/ | 从根节点选取。 |
// | 从匹配选择的当前节点选择文档中的节点&#xff0c;而不考虑它们的位置。 |
. | 选取当前节点。 |
… | 选取当前节点的父节点。 |
&#64; | 选取属性。 |
在下面的表格中&#xff0c;列出了一些路径表达式以及表达式的结果&#xff1a;
bookstore | 选取 bookstore 元素的所有子节点。 |
---|
/bookstore | 选取根元素 bookstore。注释&#xff1a;假如路径起始于正斜杠( / )&#xff0c;则此路径始终代表到某元素的绝对路径&#xff01; |
bookstore/book | 选取属于 bookstore 的子元素的所有 book 元素。 |
//book | 选取所有 book 子元素&#xff0c;而不管它们在文档中的位置。 |
bookstore//book | 选择属于 bookstore 元素的后代的所有 book 元素&#xff0c;而不管它们位于 bookstore 之下的什么位置。 |
//&#64;lang | 选取名为 lang 的所有属性。 |
谓语
谓语用来查找某个特定的节点或者包含某个指定的值的节点。
谓语被嵌在方括号中。
在下面的表格中&#xff0c;我们列出了带有谓语的一些路径表达式&#xff0c;以及表达式的结果&#xff1a;
路径表达式 | 结果 |
---|
/bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。 |
/bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素。 |
/bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素。 |
/bookstore/book[position()<‘&#39;3] | 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 |
//title[&#64;lang] | 选取所有拥有名为 lang 的属性的 title 元素。 |
//title[&#64;lang&#61;‘eng’] | 选取所有 title 元素&#xff0c;且这些元素拥有值为 eng 的 lang 属性。 |
/bookstore/book[price>35.00] | 选取 bookstore 元素的所有 book 元素&#xff0c;且其中的 price 元素的值须大于 35.00。 |
/bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素&#xff0c;且其中的 price 元素的值须大于 35.00。 |
正则表达式
Python3爬虫之正则表达式与re库主要函数
你需要掌握的数据存储
经过爬取&#xff0c;解析&#xff0c;接下来我们要将我们想要的数据存储下来&#xff0c;我们有以下几种选择方案
- json&#xff08;简单好用&#xff0c;强烈推荐&#xff09;
- csv
- excel
- mysql(需要数据库基础)
- mongoDB&#xff08;需要数据库基础&#xff09;
JSON
理想的数据交换语言&#xff0c;易于人阅读和编写&#xff0c;同时也易于机器解析和生成 &#xff0c; 并有效地提升网络传输效率 ,本质就是字符串
JSON在python中支持的数据类型
- 对象&#xff08;字典&#xff09;。使用{}。
- 数组&#xff08;列表&#xff09;。使用[]。
- 整形、浮点型、布尔类型还有null类型。
- 字符串类型&#xff08;字符串必须要用双引号&#xff0c;不能用单引号&#xff09;。
字典&#xff08;对象&#xff09;和列表&#xff08;数组&#xff09;转为JSON格式
使用json.dumps方法
import jsonbooks &#61; [{&#39;title&#39;: &#39;钢铁是怎样练成的&#39;,&#39;price&#39;: 9.8},{&#39;title&#39;: &#39;红楼梦&#39;,&#39;price&#39;: 9.9}
]json_str &#61; json.dumps(books,ensure_ascii&#61;False)
print(json_str)
因为json
在dump
的时候&#xff0c;只能存放ascii
的字符&#xff0c;因此会将中文进行转义&#xff0c;这时候我们可以使用ensure_ascii&#61;False
关闭这个特性。
在Python
中。只有基本数据类型才能转换成JSON
格式的字符串。也即&#xff1a;int
、float
、str
、list
、dict
、tuple
。
将JSON字符串dump到文件中
json
模块中除了dumps
函数&#xff0c;还有一个dump
函数&#xff0c;这个函数可以传入一个文件指针&#xff0c;直接将字符串dump
到文件中。示例代码如下&#xff1a;
import json
books &#61; [{&#39;title&#39;: &#39;钢铁是怎样练成的&#39;,&#39;price&#39;: 9.8},{&#39;title&#39;: &#39;红楼梦&#39;,&#39;price&#39;: 9.9}
]
with open(&#39;a.json&#39;,&#39;w&#39;) as fp:json.dump(books,fp)
json字符串转化成Python对象
使用json.load方法
import json
json_str &#61; &#39;[{"title": "钢铁是怎样练成的", "price": 9.8}, {"title": "红楼梦", "price": 9.9}]&#39;
books &#61; json.loads(json_str,encoding&#61;&#39;utf-8&#39;)
print(type(books))
print(books)
第一个打印输出结果为list列表类型
直接从文件中读取json并转化为python对象&#xff1a;
import json
with open(&#39;a.json&#39;,&#39;r&#39;,encoding&#61;&#39;utf-8&#39;) as fp:json_str &#61; json.load(fp)print(json_str)