一、Urllib
1.什么是互联网爬虫?
如果我们把互联网比作一张大的蜘蛛网,那一台计算机上的数据便是蜘蛛网上的一个猎物,而爬虫程序就是一只小蜘蛛,沿着蜘蛛网抓取自己想要的数据
解释1:通过一个程序,根据Url(http://www.taobao.com)进行爬取网页,获取有用信息
解释2:使用程序模拟浏览器,去向服务器发送请求,获取响应信息
2.爬虫核心?
1.爬取网页:爬取整个网页 包含了网页中所有得内容
2.解析数据:将网页中你得到的数据 进行解析
3.难点:爬虫和反爬虫之间的博弈
3.爬虫的用途?
- 数据分析/人工数据集
- 社交软件冷启动
- 舆情监控
- 竞争对手监控
4.爬虫分类?
通用爬虫:
实例
百度、360、google、sougou等搜索引擎‐‐‐伯乐在线
功能
访问网页‐>抓取数据‐>数据存储‐>数据处理‐>提供检索服务
robots协议
一个约定俗成的协议,添加robots.txt文件,来说明本网站哪些内容不可以被抓取,起不到限制作用
自己写的爬虫无需遵守
网站排名(SEO)
- 根据pagerank算法值进行排名(参考个网站流量、点击率等指标)
- 百度竞价排名
缺点
- 抓取的数据大多是无用的
2.不能根据用户的需求来精准获取数据
聚焦爬虫
功能
根据需求,实现爬虫程序,抓取需要的数据
设计思路
1.确定要爬取的url
如何获取Url
2.模拟浏览器通过http协议访问url,获取服务器返回的html代码
如何访问
3.解析html字符串(根据一定规则提取需要的数据)
如何解析
5.反爬手段?
> 1.User‐Agent:
User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版
本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。
2.代理IP
西次代理
快代理
什么是高匿名、匿名和透明代理?它们有什么区别?
1.使用透明代理,对方服务器可以知道你使用了代理,并且也知道你的真实IP。
2.使用匿名代理,对方服务器可以知道你使用了代理,但不知道你的真实IP。
3.使用高匿名代理,对方服务器不知道你使用了代理,更不知道你的真实IP。
3.验证码访问
打码平台
云打码平台
超级🦅
4.动态加载网页 网站返回的是js数据 并不是网页的真实数据
selenium驱动真实的浏览器发送请求
5.数据加密
分析js代码
6.urllib库使用
urllib.request.urlopen() 模拟浏览器向服务器发送请求
response 服务器返回的数据
response的数据类型是HttpResponse
字节‐‐>字符串
解码decode
字符串‐‐>字节
编码encode
read() 字节形式读取二进制 扩展:rede(5)返回前几个字节
readline() 读取一行
readlines() 一行一行读取 直至结束
getcode() 获取状态码
geturl() 获取url
getheaders() 获取headers
urllib.request.urlretrieve()
请求网页
请求图片
请求视频
7.请求对象的定制
UA介绍:User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统
及版本、CPU 类型、浏览器及版本。浏览器内核、浏览器渲染引擎、浏览器语言、浏览器插件等
语法:request = urllib.request.Request()
扩展:编码的由来
'''编码集的演变‐‐‐
由于计算机是美国人发明的,因此,最早只有127个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,
这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。
但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,
所以,中国制定了GB2312编码,用来把中文编进去。
你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc‐kr里,
各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。
因此,Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。
Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。
现代操作系统和大多数编程语言都直接支持Unicode。'''
8.编解码
1.get请求方式:urllib.parse.quote()
eg:
import urllib.request
import urllib.parse
url = 'https://www.baidu.com/s?wd='
headers = {'User‐Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/74.0.3729.169 Safari/537.36'
}
url = url + urllib.parse.quote('小野')
request = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(request)
print(response.read().decode('utf‐8'))
2.get请求方式:urllib.parse.urlencode()
eg:
import urllib.request
import urllib.parse
url = 'http://www.baidu.com/s?'
data = {'name':'小刚','sex':'男',
}
data = urllib.parse.urlencode(data)
url = url + data
print(url)
headers = {'User‐Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/74.0.3729.169 Safari/537.36'
}
request = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(request)
print(response.read().decode('utf‐8'))
3.post请求方式
eg:百度翻译
import urllib.request
import urllib.parse
url = 'https://fanyi.baidu.com/sug'
headers = {'user‐agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/74.0.3729.169 Safari/537.36'
}
keyword = input('请输入您要查询的单词')
data = {'kw':keyword
}
data = urllib.parse.urlencode(data).encode('utf‐8')
request = urllib.request.Request(url=url,headers=headers,data=data)
response = urllib.request.urlopen(request)
print(response.read().decode('utf‐8'))
总结:post和get区别?
1:get请求方式的参数必须编码,参数是拼接到url后面,编码之后不需要调用encode方法
2:post请求方式的参数必须编码,参数是放在请求对象定制的方法中,编码之后需要调用encode方法
案例练习:百度详细翻译
import urllib.request
import urllib.parse
url = 'https://fanyi.baidu.com/v2transapi'
headers = {# ':authority': 'fanyi.baidu.com',# ':method': 'POST',# ':path': '/v2transapi',# ':scheme': 'https',# 'accept': '*/*',# 'accept‐encoding': 'gzip, deflate, br',# 'accept‐language': 'zh‐CN,zh;q=0.9',# 'content‐length': '119',# 'content‐type': 'application/x‐www‐form‐urlencoded; charset=UTF‐8','cookie': 'REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1;
SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; PSTM=1537097513;
BIDUPSID=D96F9A49A8630C54630DD60CE082A55C; BAIDUID=0814C35D13AE23F5EAFA8E0B24D9B436:FG=1;
to_lang_often=%5B%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D%2C%7B%22value%22
%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%5D;
from_lang_often=%5B%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%2C%7B%22value%
22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D%5D; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598;
delPer=0; H_PS_PSSID=1424_21115_29522_29519_29099_29568_28835_29220_26350; PSINO=2; locale=zh;
Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1563000604,1563334706,1565592510;
Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1565592510;
yjs_js_security_passport=2379b52646498f3b5d216e6b21c6f1c7bf00f062_1565592544_js',# 'origin': 'https://fanyi.baidu.com',# 'referer': 'https://fanyi.baidu.com/translate?
aldtype=16047&query=&keyfrom=baidu&smartresult=dict&lang=auto2zh',# 'sec‐fetch‐mode': 'cors',# 'sec‐fetch‐site': 'same‐origin',# 'user‐agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',# 'x‐requested‐with': 'XMLHttpRequest',
}
data = {'from': 'en','to': 'zh','query': 'you','transtype': 'realtime','simple_means_flag': '3','sign': '269482.65435','token': '.......',
}
#参数的编码
data = urllib.parse.urlencode(data).encode('utf‐8')# 请求对象的定制
request = urllib.request.Request(url=url,headers=headers,data=data)
response = urllib.request.urlopen(request)
# 请求之后返回的所有的数据
content = response.read().decode('utf‐8')
import json
# loads将字符串转换为python对象
obj = json.loads(content)
# python对象转换为json字符串 ensure_ascii=False 忽略字符集编码
s = json.dumps(obj,ensure_ascii=False)
print(s)
9.ajax的get请求
案例:豆瓣电影
# 爬取豆瓣电影前10页数据
# https://movie.douban.com/j/chart/top_list?
type=20&interval_id=100%3A90&action=&start=0&limit=20
# https://movie.douban.com/j/chart/top_list?
type=20&interval_id=100%3A90&action=&start=20&limit=20
# https://movie.douban.com/j/chart/top_list?
type=20&interval_id=100%3A90&action=&start=40&limit=20
import urllib.request
import urllib.parse
# 下载前10页数据
# 下载的步骤:1.请求对象的定制 2.获取响应的数据 3.下载
# 每执行一次返回一个request对象
def create_request(page):base_url = 'https://movie.douban.com/j/chart/top_list?type=20&interval_id=100%3A90&action=&'headers = {'User‐Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'}data={# 1 2 3 4# 0 20 40 60'start':(page‐1)*20,'limit':20}# data编码data = urllib.parse.urlencode(data)url = base_url + datarequest = urllib.request.Request(url=url,headers=headers)return request# 获取网页源码
def get_content(request):response = urllib.request.urlopen(request)content = response.read().decode('utf‐8')return contentdef down_load(page,content):# with open(文件的名字,模式,编码)as fp:# fp.write(内容)with open('douban_'+str(page)+'.json','w',encoding='utf‐8')as fp:fp.write(content)
if __name__ == '__main__':start_page = int(input('请输入起始页码'))end_page = int(input('请输入结束页码'))for page in range(start_page,end_page+1):request = create_request(page)content = get_content(request)down_load(page,content)
10.ajax的post请求
案例:KFC官网
11.URLError\HTTPError
简介:1.HTTPError类是URLError类的子类2.导入的包urllib.error.HTTPError urllib.error.URLError3.http错误:http错误是针对浏览器无法连接到服务器而增加出来的错误提示。引导并告诉浏览者该页是哪里出
了问题。4.通过urllib发送请求的时候,有可能会发送失败,这个时候如果想让你的代码更加的健壮,可以通过try‐
except进行捕获异常,异常有两类,URLError\HTTPError
eg:
import urllib.request
import urllib.error
url = 'https://blog.csdn.net/ityard/article/details/102646738'
# url = 'http://www.goudan11111.com'
headers = {# 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,applicati
on/signed‐exchange;v=b3',# 'Accept‐Encoding': 'gzip, deflate, br',# 'Accept‐Language': 'zh‐CN,zh;q=0.9',# 'Cache‐Control': 'max‐age=0',# 'Connection': 'keep‐alive','Cookie': 'uuid_tt_dd=10_19284691370‐1530006813444‐566189;
smidV2=2018091619443662be2b30145de89bbb07f3f93a3167b80002b53e7acc61420;
_ga=GA1.2.1823123463.1543288103; dc_session_id=10_1550457613466.265727;
acw_tc=2760821d15710446036596250e10a1a7c89c3593e79928b22b3e3e2bc98b89;
Hm_lvt_e5ef47b9f471504959267fd614d579cd=1571329184;
Hm_ct_e5ef47b9f471504959267fd614d579cd=6525*1*10_19284691370‐1530006813444‐566189;
__yadk_uid=r0LSXrcNYgymXooFiLaCGt1ahSCSxMCb;
Hm_lvt_6bcd52f51e9b3dce32bec4a3997715ac=1571329199,1571329223,1571713144,1571799968;
acw_sc__v2=5dafc3b3bc5fad549cbdea513e330fbbbee00e25; firstDie=1; SESSION=396bc85c‐556b‐42bd‐
890c‐c20adaaa1e47; UserName=weixin_42565646; UserInfo=d34ab5352bfa4f21b1eb68cdacd74768;
UserToken=d34ab5352bfa4f21b1eb68cdacd74768; UserNick=weixin_42565646; AU=7A5;
UN=weixin_42565646; BT=1571800370777; p_uid=U000000; dc_tos=pzt4xf;
Hm_lpvt_6bcd52f51e9b3dce32bec4a3997715ac=1571800372;
Hm_ct_6bcd52f51e9b3dce32bec4a3997715ac=1788*1*PC_VC!6525*1*10_19284691370‐1530006813444‐
566189!5744*1*weixin_42565646;
announcement=%257B%2522isLogin%2522%253Atrue%252C%2522announcementUrl%2522%253A%2522https%253A%2
52F%252Fblogdev.blog.csdn.net%252Farticle%252Fdetails%252F102605809%2522%252C%2522announcementCo
unt%2522%253A0%252C%2522announcementExpire%2522%253A3600000%257D',# 'Host': 'blog.csdn.net',# 'Referer': 'https://passport.csdn.net/login?code=public',# 'Sec‐Fetch‐Mode': 'navigate',# 'Sec‐Fetch‐Site': 'same‐site',# 'Sec‐Fetch‐User': '?1',# 'Upgrade‐Insecure‐Requests': '1','User‐Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/77.0.3865.120 Safari/537.36',
}
try:request = urllib.request.Request(url=url,headers=headers)response = urllib.request.urlopen(request)content = response.read().decode('utf‐8')print(content)
except urllib.error.HTTPError:print(1111)
except urllib.error.URLError:print(2222)
12.cookie登录
使用案例:
1.weibo登陆
作业:qq空间的爬取
13.Handler处理器
为什么要学习handler?
urllib.request.urlopen(url)
不能定制请求头
urllib.request.Request(url,headers,data)
可以定制请求头
Handler
定制更高级的请求头(随着业务逻辑的复杂 请求对象的定制已经满足不了我们的需求(动态cookie和代理
不能使用请求对象的定制)
eg:
import urllib.request
url = 'http://www.baidu.com'
headers = {'User ‐ Agent': 'Mozilla / 5.0(Windows NT 10.0;Win64;x64) AppleWebKit / 537.36(KHTML,
likeGecko) Chrome / 74.0.3729.169Safari / 537.36'
}
request = urllib.request.Request(url=url,headers=headers)
handler = urllib.request.HTTPHandler()
opener = urllib.request.build_opener(handler)
response = opener.open(request)
print(response.read().decode('utf‐8'))
14.代理服务器
1.代理的常用功能?
1.突破自身IP访问限制,访问国外站点。
2.访问一些单位或团体内部资源
扩展:某大学FTP(前提是该代理地址在该资源的允许访问范围之内),使用教育网内地址段免费代理服务
器,就可以用于对教育网开放的各类FTP下载上传,以及各类资料查询共享等服务。
3.提高访问速度
扩展:通常代理服务器都设置一个较大的硬盘缓冲区,当有外界的信息通过时,同时也将其保存到缓冲
区中,当其他用户再访问相同的信息时, 则直接由缓冲区中取出信息,传给用户,以提高访问速度。
4.隐藏真实IP
扩展:上网者也可以通过这种方法隐藏自己的IP,免受攻击。
2.代码配置代理
创建Reuqest对象
创建ProxyHandler对象
用handler对象创建opener对象
使用opener.open函数发送请求
eg:
import urllib.request
url = 'http://www.baidu.com/s?wd=ip'
headers = {'User ‐ Agent': 'Mozilla / 5.0(Windows NT 10.0;Win64;x64) AppleWebKit / 537.36(KHTML,
likeGecko) Chrome / 74.0.3729.169Safari / 537.36'}
request = urllib.request.Request(url=url,headers=headers)
proxies = {'http':'117.141.155.244:53281'}
handler = urllib.request.ProxyHandler(proxies=proxies)
opener = urllib.request.build_opener(handler)
response = opener.open(request)
content = response.read().decode('utf‐8')
with open('daili.html','w',encoding='utf‐8')as fp:fp.write(content)
扩展:1.代理池
2.快代理
二、解析
1.xpath
xpath使用:
注意:提前安装xpath插件
(1)打开chrome浏览器
(2)点击右上角小圆点
(3)更多工具
(4)扩展程序
(5)拖拽xpath插件到扩展程序中
(6)如果crx文件失效,需要将后缀修改zip
(7)再次拖拽
(8)关闭浏览器重新打开
(9)ctrl + shift + x
(10)出现小黑框
1.安装lxml库
pip install lxml ‐i https://pypi.douban.com/simple
2.导入lxml.etree
from lxml import etree
3.etree.parse() 解析本地文件
html_tree = etree.parse('XX.html')
4.etree.HTML() 服务器响应文件
html_tree = etree.HTML(response.read().decode('utf‐8')
4.html_tree.xpath(xpath路径)
xpath基本语法:
1.路径查询
//:查找所有子孙节点,不考虑层级关系
/ :找直接子节点
2.谓词查询
//div[@id]
//div[@id="maincontent"]
3.属性查询
//@class
4.模糊查询
//div[contains(@id, "he")]
//div[starts‐with(@id, "he")]
5.内容查询
//div/h1/text()
6.逻辑运算
//div[@id="head" and @class="s_down"]
//title | //price
应用案例: 1.站长素材图片抓取并且下载(http://sc.chinaz.com/tupian/shuaigetupian.html)–》懒加载
2.JsonPath
jsonpath的安装及使用方式:
pip安装:
pip install jsonpath
jsonpath的使用:
obj = json.load(open('json文件', 'r', encoding='utf‐8'))
ret = jsonpath.jsonpath(obj, 'jsonpath语法')
教程连接(http://blog.csdn.net/luxideyao/article/details/77802389)
案例练习:淘票票
作业: 1.股票信息提取(http://quote.stockstar.com/)
2.boos直聘
3.中华英才
4.汽车之家
3.BeautifulSoup
1.基本简介
1.BeautifulSoup简称:
bs4
2.什么是BeatifulSoup?
BeautifulSoup,和lxml一样,是一个html的解析器,主要功能也是解析和提取数据
3.优缺点?
缺点:效率没有lxml的效率高
优点:接口设计人性化,使用方便
2.安装以及创建
1.安装
pip install bs4
2.导入
from bs4 import BeautifulSoup
3.创建对象
服务器响应的文件生成对象
soup = BeautifulSoup(response.read().decode(), 'lxml')
本地文件生成对象
soup = BeautifulSoup(open('1.html'), 'lxml')
注意:默认打开文件的编码格式gbk所以需要指定打开编码格式
3.节点定位
1.根据标签名查找节点
soup.a 【注】只能找到第一个a
soup.a.name
soup.a.attrs
2.函数
(1).find(返回一个对象)
find('a'):只找到第一个a标签
find('a', title='名字')
find('a', class_='名字')
(2).find_all(返回一个列表)
find_all('a') 查找到所有的a
find_all(['a', 'span']) 返回所有的a和span
find_all('a', limit=2) 只找前两个a
(3).select(根据选择器得到节点对象)【推荐】1.elementeg:p2..classeg:.firstname3.#ideg:#firstname4.属性选择器[attribute]eg:li = soup.select('li[class]')[attribute=value]eg:li = soup.select('li[class="hengheng1"]')5.层级选择器element elementdiv pelement>elementdiv>pelement,elementdiv,peg:soup = soup.select('a,span')
4.节点信息
(1).获取节点内容:适用于标签中嵌套标签的结构obj.stringobj.get_text()【推荐】
(2).节点的属性tag.name 获取标签名eg:tag = find('li)print(tag.name)tag.attrs将属性值作为一个字典返回
(3).获取节点属性obj.attrs.get('title')【常用】obj.get('title')obj['title']
应用实例: 1.股票信息提取(http://quote.stockstar.com/)
2.中华英才网-旧版
3 .腾讯公司招聘需求抓取(https://hr.tencent.com/index.php)
三、Selenium
1.Seleniu
1.什么是selenium?
(1)Selenium是一个用于Web应用程序测试的工具。
(2)Selenium 测试直接运行在浏览器中,就像真正的用户在操作一样。
(3)支持通过各种driver(FirfoxDriver,IternetExplorerDriver,OperaDriver,ChromeDriver)驱动
真实浏览器完成测试。
(4)selenium也是支持无界面浏览器操作的。
2.为什么使用selenium?
模拟浏览器功能,自动执行网页中的js代码,实现动态加载
3.如何安装selenium?
(1)操作谷歌浏览器驱动下载地址 http://chromedriver.storage.googleapis.com/index.html
(2)谷歌驱动和谷歌浏览器版本之间的映射表
http://blog.csdn.net/huilan_same/article/details/51896672
(3)查看谷歌浏览器版本
谷歌浏览器右上角‐‐>帮助‐‐>关于
(4)pip install selenium
4.selenium的使用步骤?
(1)导入:from selenium import webdriver
(2)创建谷歌浏览器操作对象:path = 谷歌浏览器驱动文件路径browser = webdriver.Chrome(path)
(3)访问网址url = 要访问的网址browser.get(url)
4‐1:selenium的元素定位?
元素定位:自动化要做的就是模拟鼠标和键盘来操作来操作这些元素,点击、输入等等。操作这些元素前首先
要找到它们,WebDriver提供很多定位元素的方法
方法:
1.find_element_by_id
eg:button = browser.find_element_by_id('su')
2.find_elements_by_name
eg:name = browser.find_element_by_name('wd')
3.find_elements_by_xpath
eg:xpath1 = browser.find_elements_by_xpath('//input[@id="su"]')
4.find_elements_by_tag_name
eg:names = browser.find_elements_by_tag_name('input')
5.find_elements_by_css_selector
eg:my_input = browser.find_elements_by_css_selector('#kw')[0]
6.find_elements_by_link_text
eg:browser.find_element_by_link_text("新闻")
4‐2:访问元素信息
获取元素属性
.get_attribute('class')
获取元素文本
.text
获取标签名
.tag_name
4‐3:交互
点击:click()
输入:send_keys()
后退操作:browser.back()
前进操作:browser.forword()
模拟JS滚动:
js='document.documentElement.scrollTop=100000'
browser.execute_script(js) 执行js代码
获取网页代码:page_source
退出:browser.quit()
2.Phantomjs
1.什么是Phantomjs?
(1)是一个无界面的浏览器
(2)支持页面元素查找,js的执行等
(3)由于不进行css和gui渲染,运行效率要比真实的浏览器要快很多
2.如何使用Phantomjs?
(1)获取PhantomJS.exe文件路径path
(2)browser = webdriver.PhantomJS(path)
(3)browser.get(url)
扩展:保存屏幕快照:browser.save_screenshot('baidu.png')
3.Chrome handless
Chrome-headless 模式, Google 针对 Chrome 浏览器 59版 新增加的一种模式,可以让你不打开UI界面的情况下
使用 Chrome 浏览器,所以运行效果与 Chrome 保持完美一致。
1.系统要求:ChromeUnix\Linux 系统需要 chrome >= 59Windows 系统需要 chrome >= 60Python3.6Selenium==3.4.*ChromeDriver==2.31
2.配置:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('‐‐headless')
chrome_options.add_argument('‐‐disable‐gpu')
path = r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
chrome_options.binary_location = path
browser = webdriver.Chrome(chrome_options=chrome_options)
browser.get('http://www.baidu.com/')
3.配置封装:from selenium import webdriver
#这个是浏览器自带的 不需要我们再做额外的操作
from selenium.webdriver.chrome.options import Options
def share_browser():#初始化chrome_options = Options()chrome_options.add_argument('‐‐headless')chrome_options.add_argument('‐‐disable‐gpu')#浏览器的安装路径 打开文件位置#这个路径是你谷歌浏览器的路径path = r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'chrome_options.binary_location = pathbrowser = webdriver.Chrome(chrome_options=chrome_options)return browser封装调用:from handless import share_browser
browser = share_browser()
browser.get('http://www.baidu.com/')
browser.save_screenshot('handless1.png')
作业:京东
四、requests
1.基本使用
1.文档:
官方文档
http://cn.python‐requests.org/zh_CN/latest/
快速上手
http://cn.python‐requests.org/zh_CN/latest/user/quickstart.html
2.安装
pip install requests
3.response的属性以及类型
类型 :models.Response
r.text : 获取网站源码
r.encoding :访问或定制编码方式
r.url :获取请求的url
r.content :响应的字节类型
r.status_code :响应的状态码
r.headers :响应的头信息
2.get请求
requests.get()eg:import requestsurl = 'http://www.baidu.com/s?'headers = {'User‐Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/65.0.3325.181 Safari/537.36'}data = {'wd':'北京'}response = requests.get(url,params=data,headers=headers)
定制参数参数使用params传递参数无需urlencode编码不需要请求对象的定制请求资源路径中?可加可不加
3.post请求
requests.post()
百度翻译:
eg:
import requests
post_url = 'http://fanyi.baidu.com/sug'
headers={'User‐Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}
data = {'kw': 'eye'
}
r = requests.post(url = post_url,headers=headers,data=data)
6:get和post区别?
1: get请求的参数名字是params post请求的参数的名字是data
2: 请求资源路径后面可以不加?
3: 不需要手动编解码
4: 不需要做请求对象的定制
4.代理
7:proxy定制
在请求中设置proxies参数
参数类型是一个字典类型
eg:
import requests
url = 'http://www.baidu.com/s?'
headers = {'user‐agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/65.0.3325.181 Safari/537.36'
}
data = {'wd':'ip'
}
proxy = {'http':'219.149.59.250:9797'
}
r = requests.get(url=url,params=data,headers=headers,proxies=proxy)
with open('proxy.html','w',encoding='utf‐8') as fp:fp.write(r.text)
5.cookie定制
8:cookie定制
应用案例:
(1)古诗文网(需要验证)
(2)云打码平台用户登陆 actionuser action开发者登陆 actioncode action
作业:国家统计局(http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2017/)共计68万条数
五、scrapy
1.scrapy
(1)scrapy是什么?
Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理
或存储历史数据等一系列的程序中。
(2)安装scrapy:pip install scrapy
安装过程中出错:如果安装有错误!!!!pip install Scrapybuilding 'twisted.test.raiser' extensionerror: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++
Build Tools": http://landinghub.visualstudio.com/visual‐cpp‐build‐tools
解决方案:http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted下载twisted对应版本的whl文件(如我的Twisted‐17.5.0‐cp36‐cp36m‐ win_amd64.whl),cp后面是python版本,amd64代表64位,运行命令:pip install C:\Users\...\Twisted‐17.5.0‐cp36‐cp36m‐win_amd64.whlpip install Scrapy
如果再报错python ‐m pip install ‐‐upgrade pip
如果再报错 win32
解决方法:pip install pypiwin32
再报错:使用anaconda使用步骤:打开anaconda点击environments点击not installed输入scrapyapply在pycharm中选择anaconda的环境
1.scrapy项目的创建以及运行
1.创建scrapy项目:
终端输入 scrapy startproject 项目名称
2.项目组成:
spiders__init__.py自定义的爬虫文件.py ‐‐‐》由我们自己创建,是实现爬虫核心功能的文件__init__.pyitems.py ‐‐‐》定义数据结构的地方,是一个继承自scrapy.Item的类middlewares.py ‐‐‐》中间件 代理pipelines.py ‐‐‐》管道文件,里面只有一个类,用于处理下载数据的后续处理默认是300优先级,值越小优先级越高(1‐1000)settings.py ‐‐‐》配置文件 比如:是否遵守robots协议,User‐Agent定义等
3.创建爬虫文件:(1)跳转到spiders文件夹 cd 目录名字/目录名字/spiders(2)scrapy genspider 爬虫名字 网页的域名
爬虫文件的基本组成:继承scrapy.Spider类name = 'baidu' ‐‐‐》 运行爬虫文件时使用的名字allowed_domains ‐‐‐》 爬虫允许的域名,在爬取的时候,如果不是此域名之下的url,会被过滤掉start_urls ‐‐‐》 声明了爬虫的起始地址,可以写多个url,一般是一个parse(self, response) ‐‐‐》解析数据的回调函数response.text ‐‐‐》响应的是字符串response.body ‐‐‐》响应的是二进制文件response.xpath()‐》xpath方法的返回值类型是selector列表extract() ‐‐‐》提取的是selector对象的是dataextract_first() ‐‐‐》提取的是selector列表中的第一个数据
4.运行爬虫文件:
scrapy crawl 爬虫名称
注意:应在spiders文件夹内执行
3.scrapy架构组成
(1)引擎 ‐‐‐》自动运行,无需关注,会自动组织所有的请求对象,分发给下载器
(2)下载器 ‐‐‐》从引擎处获取到请求对象后,请求数据
(3)spiders ‐‐‐》Spider类定义了如何爬取某个(或某些)网站。包括了爬取的动作(例
如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item)。 换句话说,Spider就是您定义爬取的动作及
分析某个网页(或者是有些网页)的地方。
(4)调度器 ‐‐‐》有自己的调度规则,无需关注
(5)管道(Item pipeline) ‐‐‐》最终处理数据的管道,会预留接口供我们处理数据
当Item在Spider中被收集之后,它将会被传递到Item Pipeline,一些组件会按照一定的顺序执行对Item的处理。
每个item pipeline组件(有时称之为“Item Pipeline”)是实现了简单方法的Python类。他们接收到Item并通过它执行
一些行为,同时也决定此Item是否继续通过pipeline,或是被丢弃而不再进行处理。以下是item pipeline的一些典型应用:
1. 清理HTML数据
2. 验证爬取的数据(检查item包含某些字段)
3. 查重(并丢弃)
4. 将爬取结果保存到数据库中
4.scrapy工作原理
案例:1.汽车之家
2.scrapy shell
1.什么是scrapy shell?Scrapy终端,是一个交互终端,供您在未启动spider的情况下尝试及调试您的爬取代码。 其本意是用来测试提取
数据的代码,不过您可以将其作为正常的Python终端,在上面测试任何的Python代码。
该终端是用来测试XPath或CSS表达式,查看他们的工作方式及从爬取的网页中提取的数据。 在编写您的spider时,该
终端提供了交互性测试您的表达式代码的功能,免去了每次修改后运行spider的麻烦。
一旦熟悉了Scrapy终端后,您会发现其在开发和调试spider时发挥的巨大作用。
2.安装ipython
安装:pip install ipython
简介:如果您安装了 IPython ,Scrapy终端将使用 IPython (替代标准Python终端)。 IPython 终端与其他相
比更为强大,提供智能的自动补全,高亮输出,及其他特性。
3.应用:(1)scrapy shell www.baidu.com(2)scrapy shell http://www.baidu.com(3) scrapy shell "http://www.baidu.com"(4) scrapy shell "www.baidu.com"
语法:(1)response对象:response.bodyresponse.textresponse.urlresponse.status(2)response的解析:response.xpath() (常用)使用xpath路径查询特定元素,返回一个selector列表对象response.css()使用css_selector查询元素,返回一个selector列表对象获取内容 :response.css('#su::text').extract_first()获取属性 :response.css('#su::attr(“value”)').extract_first()(3)selector对象(通过xpath方法调用返回的是seletor列表)extract()提取selector对象的值如果提取不到值 那么会报错使用xpath请求到的对象是一个selector对象,需要进一步使用extract()方法拆包,转换为unicode字符串extract_first()提取seletor列表中的第一个值如果提取不到值 会返回一个空值返回第一个解析到的值,如果列表为空,此种方法也不会报错,会返回一个空值xpath()css()注意:每一个selector对象可以再次的去使用xpath或者css方法
3.yield
- 带有 yield 的函数不再是一个普通函数,而是一个生成器generator,可用于迭代
- yield 是一个类似 return 的关键字,迭代一次遇到yield时就返回yield后面(右边)的值。重点是:下一次迭代时,从上一次迭代遇到的yield后面的代码(下一行)开始执行
- 简要理解:yield就是 return 返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后(下一行)开始
案例:
1.当当网 (1)yield(2).管道封装(3).多条管道下载 (4)多页数据下载
2.电影天堂 (1)一个item包含多级页面的数据
4.Mysql
(1)下载(https://dev.mysql.com/downloads/windows/installer/5.7.html)
(2)安装(https://jingyan.baidu.com/album/d7130635f1c77d13fdf475df.html)
5.pymysql的使用步骤
1.pip install pymysql
2.pymysql.connect(host,port,user,password,db,charset)
3.conn.cursor()
4.cursor.execute()
6.CrawlSpider
1.继承自scrapy.Spider
2.独门秘笈CrawlSpider可以定义规则,再解析html内容的时候,可以根据链接规则提取出指定的链接,然后再向这些链接发
送请求所以,如果有需要跟进链接的需求,意思就是爬取了网页之后,需要提取链接再次爬取,使用CrawlSpider是非常
合适的
3.提取链接链接提取器,在这里就可以写规则提取指定链接
scrapy.linkextractors.LinkExtractor(allow = (), # 正则表达式 提取符合正则的链接deny = (), # (不用)正则表达式 不提取符合正则的链接allow_domains = (), # (不用)允许的域名deny_domains = (), # (不用)不允许的域名restrict_xpaths = (), # xpath,提取符合xpath规则的链接restrict_css = () # 提取符合选择器规则的链接)
4.模拟使用正则用法:links1 = LinkExtractor(allow=r'list_23_\d+\.html')xpath用法:links2 = LinkExtractor(restrict_xpaths=r'//div[@class="x"]')css用法:links3 = LinkExtractor(restrict_css='.x')
5.提取连接link.extract_links(response)
6.注意事项【注1】callback只能写函数名字符串, callback='parse_item'【注2】在基本的spider中,如果重新发送请求,那里的callback写的是 callback=self.parse_item 【注‐
‐稍后看】follow=true 是否跟进 就是按照提取连接规则进行提取
运行原理:
7.CrawlSpider案例
需求:读书网数据入库
1.创建项目:scrapy startproject dushuproject
2.跳转到spiders路径 cd\dushuproject\dushuproject\spiders
3.创建爬虫类:scrapy genspider ‐t crawl read www.dushu.com
4.items
5.spiders
6.settings
7.pipelines数据保存到本地数据保存到mysql数据库
8. 数据入库
(1)settings配置参数:DB_HOST = '192.168.231.128'DB_PORT = 3306DB_USER = 'root'DB_PASSWORD = '1234'DB_NAME = 'test'DB_CHARSET = 'utf8'
(2)管道配置from scrapy.utils.project import get_project_settingsimport pymysqlclass MysqlPipeline(object):#__init__方法和open_spider的作用是一样的#init是获取settings中的连接参数def __init__(self):settings = get_project_settings()self.host = settings['DB_HOST']self.port = settings['DB_PORT']self.user = settings['DB_USER']self.pwd = settings['DB_PWD']self.name = settings['DB_NAME']self.charset = settings['DB_CHARSET']self.connect()# 连接数据库并且获取cursor对象def connect(self):self.conn = pymysql.connect(host=self.host,port=self.port,user=self.user,password=self.pwd,db=self.name,charset=self.charset)self.cursor = self.conn.cursor()def process_item(self, item, spider):sql = 'insert into book(image_url, book_name, author, info) values("%s",
"%s", "%s", "%s")' % (item['image_url'], item['book_name'], item['author'], item['info'])sql = 'insert into book(image_url,book_name,author,info) values
("{}","{}","{}","{}")'.format(item['image_url'], item['book_name'], item['author'],
item['info'])# 执行sql语句self.cursor.execute(sql)self.conn.commit()return itemdef close_spider(self, spider):self.conn.close()self.cursor.close()
9.日志信息和日志等级
(1)日志级别:CRITICAL:严重错误ERROR: 一般错误WARNING: 警告INFO: 一般信息DEBUG: 调试信息默认的日志等级是DEBUG只要出现了DEBUG或者DEBUG以上等级的日志那么这些日志将会打印
(2)settings.py文件设置:默认的级别为DEBUG,会显示上面所有的信息在配置文件中 settings.pyLOG_FILE : 将屏幕显示的信息全部记录到文件中,屏幕不再显示,注意文件后缀一定是.logLOG_LEVEL : 设置日志显示的等级,就是显示哪些,不显示哪些
10.scrapy的post请求
(1)重写start_requests方法:def start_requests(self)
(2) start_requests的返回值:scrapy.FormRequest(url=url, headers=headers, callback=self.parse_item, formdata=data)url: 要发送的post地址headers:可以定制头信息callback: 回调函数formdata: post所携带的数据,这是一个字典
11.代理
(1)到settings.py中,打开一个选项DOWNLOADER_MIDDLEWARES = {'postproject.middlewares.Proxy': 543,}
(2)到middlewares.py中写代码def process_request(self, request, spider):request.meta['proxy'] = 'https://113.68.202.10:9999'return None