Python 爬虫
1、网络爬虫
网络爬虫(又被称为网页蜘蛛,网络机器人,网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。
2、爬虫的架构
Python 爬虫架构主要由五个部分组成,分别是调度器、URL管理器、网页下载器、网页解析器、应用程序(爬取的有价值数据)。
调度器:相当于一台电脑的CPU,主要负责调度URL管理器、下载器、解析器之间的协调工作。 URL管理器:包括待爬取的URL地址和已爬取的URL地址,防止重复抓取URL和循环抓取URL,实现URL管理器主要用三种方式,通过内存、数据库、缓存数据库来实现。 网页下载器:通过传入一个URL地址来下载网页,将网页转换成一个字符串,网页下载器有urllib2(Python官方基础模块)包括需要登录、代理、和cookie,requests(第三方包) 网页解析器:将一个网页字符串进行解析,可以按照我们的要求来提取出我们有用的信息,也可以根据DOM树的解析方式来解析。网页解析器有正则表达式(直观,将网页转成字符串通过模糊匹配的方式来提取有价值的信息,当文档比较复杂的时候,该方法提取数据的时候就会非常的困难)、html.parser(Python自带的)、beautifulsoup(第三方插件,可以使用Python自带的html.parser进行解析,也可以使用lxml进行解析,相对于其他几种来说要强大一些)、lxml(第三方插件,可以解析 xml 和 HTML),html.parser 和 beautifulsoup 以及 lxml 都是以 DOM 树的方式进行解析的。 应用程序:就是从网页中提取的有用数据组成的一个应用。
3、爬虫的基本流程
模拟浏览器发送请求(获取网页代码)->提取有用的数据->存放于数据库或文件中
1)发送请求
urllib.request 在下载好的IDLE中 -> Help -> python Docs,点进去; 都是python的文挡,所有python内置的东西都在里面能找到用法、含义等。 搜索 urllib.request;
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
#如果data参数没有值,默认用get方式提交,如果有值,以post方式提交
#要用 urllib.parse.urlencode()的编码格式,把data进行编码
urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
#url应该是包含有效URL的字符串。
1、请求网页链接
eg1:读取elementUI中返回的文档
#读取elementUI中返回的文档
import urllib.request as req #引入urllib.request
res = req.urlopen('http://element-cn.eleme.io/#/zh-CN/component/input'); #打开链接
html = res.read(); #读取返回值
print(html);
html = html.decode('utf-8'); #解析,根据页面的格式进行解析
print(html)
eg2:下载图片
#下载图片
import urllib.request as req; #引入 urllib.request
res = req.urlopen('http://placekitten.com/500/600'); #打开对应的图片链接
cat_img = res.read(); #读取请求回来的数据
with open('cat_imng.jpg', 'wb') as f: #创建文件并用二进制写入图片 使用with语句
f.write(cat_img);
2、请求头
head 可以设置head字段来改变请求头的设置 在一般爬虫里面很多都不是浏览器发起的请求,所以可以在请求头里面设置,模拟浏览器请求。写入'user-agent'字段。 包括cookie等信息都可以在head里面进行设置。
head = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
3、传参
传参就要引入参数编码,把参数进行编码之后在传过去。 urllib.parse
import urllib.request as req;
import ssl;
import urllib.parse;
context = ssl._create_unverified_context();
url = 'https://waimaicenter.superboss.cc/shopOrderRecord/queryFkData.rjson';
data = {
'appType': 'ELE_ACCOUNTING',
'endTime': '2018-11-10 23:59:59',
'pageNo': '1',
'pageSize': '10',
'searchKey': '',
'shopOption': '',
'startTime': '2018-11-10 00:00:00',
'version': '',
'orderColumn':'',
'orderType': '',
'bizType': '',
'timeType': '1',
'orderPayType':'',
'fufeiType': ''
}
head = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
data = urllib.parse.urlencode(data).encode('utf-8');
res1 = req.Request(url, data, head);
res = req.urlopen(res1, context=context);
print(res.read().decode('utf-8'));
#直接用urllib.request.urlopen()其实python在内部做了两部处理:
#req = urllib.request.Request(url, data, headers);
#res = urllib.request.urlopen(req);
4、https
有时候请求的链接是https的,这个时候直接爬取的话就会报错,抛出异常。
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1045)>
此时就需要引入ssl;有两种解决办法: 1) import ssl ssl._create_default_https_context = ssl._create_unverified_context 2) import ssl context = ssl._create_unverified_context() res = urllib.request.urlopen(url, data, context=context);
import urllib.request as req;
import ssl;
context = ssl._create_unverified_context();
res = req.urlopen('https:', context=context);
print(res.read().decode('utf-8'));
5、cookie
有时候需要携带cookie进行一系列验证 此时就可以在head中添加对应接口所需的cookie信息即可,就可以对一些需要cookie的请求来爬取。
head = {
'cookie': '',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
2)获取响应内容
如果一个服务能正常响应,则会得到一个Response Response包含:html,json,图片,视频等。
res = req.urlopen(url, context=context);
变量res就是请求一个URL之后得到的响应值。
3)处理响应数据(解析内容)
解析html数据:正则表达式(RE模块),第三方解析库如Beautifulsoup,pyquery,Scrapy等。 解析json数据:json模块。 解析二进制数据:以wb的方式写入文件。
4)保存数据
数据库(mysql等) 保存成本地文件
python链接mysql
pip3 install pymysql #使用第三方工具包
import pymysql
db = pymysql.connect("","","","");
cursor = db.cursor();
sql = '''delete from test_employee where age > 20''';#sql语句
cursor.execute(sql);
# 提交到数据库执行
db.commit();
db.close();#关闭