主要内容:
1 爬虫理论:
a 爬虫的概念: 编写程序模拟浏览器上网, 然后让其去网上爬取数据的过程
b 爬虫的分类:
通用爬虫: 搜索引擎“抓取系统(爬虫程序)”的重要组成部分。
聚焦爬虫: 根据指定的需求抓取页面中指定的内容。
c 反爬机制:门户网站给通过相关的技术手段或者策略来阻止爬虫进行数据的抓取.
d 反反爬策略: 爬虫程序通过相关的技术或者策略破解反爬.
e 反爬机制: robtos.txt协议
f http:超文本传输协议。客户端和服务器端进行数据交互的一种交互形式。
h https:安全超文本传输协议。SSL加密层。
l user-agent: 请求载体的身份标识, content_type :响应的数据类型
m 对称秘钥加密: 非对称秘钥加密, 证书加密
2 requests 模块: 是python中一个原生的基于网络请求的模块
a : 安装 pip3 install requests
b : 使用流程: 指定url, 发起请求, 获取页面数据, 页面数据持久化存储
c : 爬虫事例:
import requests
#1.指定url
url = 'https://www.sogou.com'
#2.发起请求:get返回值为响应对象
response = requests.get(url=url,proxies={'https':'80.78.72.152:39172'})
#3.获取页面数据:text属性返回的是字符串类型的页面数据,content返回的是二进制的页面数据
#page_text = response.content
page_text = response.text
#4
with open('./sogou.html','w',encoding='utf-8') as fp:
fp.write(page_text)
反爬机制: 对ua进行伪装操作
#UA反爬机制:对UA进行伪装操作
#请求头信息
import requests
url = 'https://www.qiushibaike.com/'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'
}
#headers参数:请求的请求头信息
response = requests.get(url=url,headers=headers)
response
抓取肯德基餐厅的位置信息:
import requests kdj_info = [] url = "http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword" city = input("请输入一个城市的名字:>>>") data = { "cname":"", "pid":"", "keyword":city, "pageIndex": 1, "pageSize": 10, } headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36' } response = requests.post(url=url, headers=headers, data=data) result = response.json() # 构建自己想要的数据结构 for index, one in enumerate(result["Table1"]): # print(index, one) kdj_info.append({"序号":index + 1, "店名":one["storeName"], "地址":one["addressDetail"]}) for store_info in kdj_info: print(store_info)
爬去药监总局的相关信息:
#http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsList import requests first_url = "http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsList" id_list = [] detail_list = [] result_list = [] start_page = int(input("请输入开始页")) end_page = int(input("请输入结束页")) headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36' } for i in range(start_page, end_page+1): data = { 'on': 'true', 'page':str(i), 'pageSize': '15', 'productName':'', 'conditionType': '1', 'applyname':'', 'applysn':'' } response = requests.post(url=first_url, data=data, headers=headers).json() for info in response["list"]: id_list.append(info["ID"]) res_url = "http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsById" for id in id_list: data = { "id":id } res_response = requests.post(url=res_url, data=data, headers=headers).json() detail_list.append(res_response) # print(detail_list) # 数据结构的构建 for detail in detail_list: result_list.append({"创始人":detail["businessPerson"], "地址":detail["epsAddress"]}) for every_info in result_list: print(every_info)
3 爬图片
import requests
from urllib import request,parse
url = 'http://pics.sc.chinaz.com/files/pic/pic9/201812/zzpic15565.jpg'
img_data = requests.get(url=url).content
with open('./siwa.jpg','wb') as fp:
fp.write(img_data)
爬取图片的第二种方法
url = 'http://pics.sc.chinaz.com/files/pic/pic9/201812/zzpic15565.jpg'
request.urlretrieve(url=url,filename='./meinv.png')
request.urlopen(url=url).read()
# url = 'https://www.baidu.com/s?wd=人民币'
# request.urlopen(url=url)
parse.quote('人民币')
4 正则匹配: . * ? re.S re.M:https://www.cnblogs.com/pugang/p/10123285.html
a re.s的用法:在Python的正则表达式中,有一个参数为re.S。它表示“.”(不包含外侧双引号,下同)的作用扩展到整个字符串,包括“\n”。看如下代码:
import re
a = '''asdfsafhellopass:
234455
worldafdsf
'''
b = re.findall('hello(.*?)world',a)
c = re.findall('hello(.*?)world',a,re.S)
print 'b is ' , b
print 'c is ' , c
运行结果
b is []
c is ['pass:\n\t234455\n\t']
正则表达式中,“.”的作用是匹配除“\n”以外的任何字符,也就是说,它是在一行中进行匹配。这里的“行”是以“\n”进行区分的。a字符串有每行的末尾有一个“\n”,不过它不可见。
如果不使用re.S参数,则只在每一行内进行匹配,如果一行没有,就换下一行重新开始,不会跨行。而使用re.S参数以后,正则表达式会将这个字符串作为一个整体,将“\n”当做一个普通的字符加入到这个字符串中,在整体中进行匹配。
b re.M:仍然是整句话,这是因为^和$只匹配整个字符串的起始和结束。在多行模式下,^除了匹配整个字符串的起始位置,还匹配换行符后面的位置;$除了匹配整个字符串的结束位置,还匹配换行符前面的位置.
>>> re.findall(r'^This.*?line.$', a, flags=re.DOTALL+re.MULTILINE)
['This is the first line.', 'This is the second line.', 'This is the third line.']
更本质的说法是 多行模式改变了^和$的匹配行为
5 正则解析
#1.检查页面数据是否为动态加载出来的
#2.获取页面源码数据
import re
import requests
from urllib import request
import os
if not os.path.exists('qiutu'):
os.mkdir('qiutu')
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
}
url = 'https://www.qiushibaike.com/pic/'
page_text = requests.get(url=url,headers=headers).text
#3.解析img标签的src属性值
ex = '<div class="thumb">.*?<img src="(.*?)" alt=.*?</div>'
img_url_list = re.findall(ex,page_text,re.S)
for img_url in img_url_list:
img_url = 'https:'+img_url
imgPath = 'qiutu/'+img_url.split('/')[-1]
#4.对图片url发请求
#5.持久化存储
request.urlretrieve(url=img_url,filename=imgPath)
print(imgPath+'下载成功!!!')