selenium+phantomjs,headerlesschrome
1.selenium是什么:是一个浏览器的自动化测试框架,通过selenium可以写代码,通过运行代码,可以让谷歌浏览器做自动化的工作。
实现:
1.安装:pip install selenium
演示:操作谷歌浏览器,其实操作的是谷歌浏览器的驱动,由驱动来驱动浏览器,既然这样,先下载驱动.(要下载对应版本的驱动)
谷歌驱动下载地址
http://chromedriver.storage.googleapis.com/index.html
浏览器的方法
http://blog.csdn.net/huilan_same/article/details/51896672
浏览器的方法
find_element_by_id 根据id查找指定的对象
find_elements_by_name 根据name查找
find_elements_by_xpath 根据xpath查找
find_elements_by_tag_name 根据标签名称进行查找
find_elements_by_class_name 根据类名进行查找
find_elements_by_css_selector 根据选择器进行查找
find_elements_by_link_text 根据a链接的内容进行查找
实例:
from selenium import webdriver 英[səˈli:niəm]
import time
#根据谷歌驱动,创建谷歌浏览器对象
path = r'C:\Users\Administrator\Downloads\chromedriver.exe'
browser = webdriver.Chrome(path)
#打开百度
firsturl = 'http://www.baidu.com/'
browser.get(firsturl)
time.sleep(2)
# 查找输入框
myinput = browser.find_element_by_id('kw')
#向框里面写内容
myinput.send_keys('周杰伦')
time.sleep(3)
#查找点击一下按钮
button =browser.find_element_by_id('su')
button.click()
time.sleep(5)
#查找周杰伦百度百科
#注意:按内容查找必须是a链接的完整文本内容才可以
baike=browser.find_elements_by_link_text('周杰伦_百度百科')[0]
baike.click()
time.sleep(5)
#退出浏览器
browser.quit()
2.phantomjs
phantomjs是什么,是一款浏览器,是无界面的浏览器,它的设计本质不是用来上网的,既然是浏览器,就有浏览器的功能。就可以解释html,css,js,在爬虫的过程中,经常会有这种反爬机制:html是动态加载的,因为js的dom操作,可以动态的给网页添加和删除内容,遇到DOM,如何解决:
(1)捕获接口,从接口解析数据.
(2)通过phantomjs爬取(大招)(效率不高).
专业图片网站:防盗链(meizitu)
还有一种反爬机制:懒加载技术
真正上网的时候,会遇到滚动条加载,这种网站信息难以捕获
可以通过phantomjs模拟滚动条滚动到底部
from selenium import webdriver
import time
# 找到phantomjs路径
path = r'E:\phantomjs\phantomjs-2.1.1-windows\bin\phantomjs.exe'2.1.1-windows\bin\phantomjs.exe'
# 创建浏览器对象
browser = webdriver.PhantomJS(path)
browser.get('http://www.baidu.com/')
time.sleep(2)
# 拍照片的方式
browser.save_screenshot(r'phantomjs\baidu1.png')
# 往下要执行的操作,就是走一步拍一步的过程
browser.find_element_by_id('kw').send_keys('美女')
browser.find_element_by_id('su').click()
time.sleep(2)
browser.save_screenshot(r'phantomjs\baidu2.png')
browser.quit()
滚动到底部
from selenium import webdriver
import time
# 找到phantomjs路径
path = r'C:\Users\zbli\Desktop\1803\day07\ziliao\phantomjs-2.1.1-windows\bin\phantomjs.exe'
# 创建浏览器对象
browser = webdriver.PhantomJS(path)
browser.get('https://movie.douban.com/typerank?type_name=%E5%8A%A8%E4%BD%9C&type=5&interval_id=100:90&action=')
time.sleep(2)
browser.save_screenshot(r'phantomjs\douban1.png')
# 模拟滚动条滚动到底部
js = 'document.body.scrollTop=10000'
browser.execute_script(js)
time.sleep(3)
browser.save_screenshot(r'phantomjs\douban2.png')
browser.quit()
(3)懒加载技术(sc.chinaz.com)
div/a/img/@src
但是这样写遇到懒加载反爬获取到的是一个空列表
解决方式:div/a/img/@src2 此时才能找到希望获取到的链接
为啥改变链接名称就可以找到呢:
为什么引入懒加载:
给你一个网页,假如网页中有一百个图片,请问这个网页呈现在你面前,一共向服务器发送了多少次请求(17个requests)
一个·js,一个html都是一个请求,所以如果是100个图片,则有101次请求,没必要把不显示的图片显示在用户面前(只在可视区内显示),不显示的地方如果你往下拉,再才会显示其他图片。这就是懒加载的机制
如何实现:所以的图片img标签里面不写src属性,写src2属性,但是此时src2仅仅是为了保存图片路径,没有其他意义。然后通过js的监听,当图片出现在可视区的时候,通过js动态的将src2属性改成src,所以图片才会顺利的呈现出来。每一个图片都是一个请求,为了只显示可视区内的图片。
以后但凡遇到:src2,data-src,class==lazy等,就是懒加载机制
phantomjs就是一款浏览器,肯定可以执行js,我们要查看执行之后的网页代码
from selenium import webdriver
import time
# 找到phantomjs路径
path = r'C:\Users\zbli\Desktop\1803\day07\ziliao\phantomjs-2.1.1-windows\bin\phantomjs.exe'
# 创建浏览器对象
browser = webdriver.PhantomJS(path)
browser.get('http://sc.chinaz.com/tupian/fengjingtupian.html')
time.sleep(2)
browser.save_screenshot(r'phantomjs\tupian1.png')
js = 'document.body.scrollTop=10000'
browser.execute_script(js)
time.sleep(3)
browser.save_screenshot(r'phantomjs\tupian2.png')
# 保存执行js之后的网页源码
with open('tupian.html', 'w', encoding='utf8') as fp:
fp.write(browser.page_source)
browser.quit()
定义:没有头部的谷歌浏览器,无界面的谷歌浏览器。正是由于谷歌有了无界面的浏览器,所以phantomjs就倒闭了, 不再维护了,尽量使用无界面的谷歌浏览器。
要求:如果是linux,谷歌浏览器要求版本在59+以上,windows要求60+以上
使用:
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
谷歌无界面模式
#操作无界面谷歌
from selenium import webdriver
import time
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
#让谷歌浏览器以无界面模式启动
path = r'C:\Users\Administrator\Downloads\chromedriver.exe'
browser = webdriver.Chrome(path,chrome_options=chrome_options)
browser.get('http://www.baidu.com')
time.sleep(2)
browser.save_screenshot(r"C:\Users\Administrator\Desktop\chrome.png")
#以后的操作和phantomjs同理
browser.quit()
原理介绍:
(1)http协议特性,(无状态协议),服务器一直在监听浏览器发的请求,得到响应,请求与响应过程称为一次交互,两次请求都是不同的请求,没有任何关系,问题出现:身份问题(登陆问题),当登陆成功了,服务器会给你发一个狗牌,在响应的时候将这些信息都写到了浏览器中,下一次浏览器发送请求的的时候带着狗牌过去就可以了
(2)模拟登陆的实现
想通过代码访问登陆后的页面,
1.带着牌过去,牌从哪里来?抓包,抓到浏览器访问的时候的狗牌,将cookie给抓取到,然后写到程序中的headers头部里面(万能)
2.通过代码模拟登陆,模拟发送post即可。
实例:登陆有验证码的古诗文网
验证码下载到本地,让用户手动输
from bs4 import BeautifulSoup
import requests
import urllib.request
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
}
def download_image(s):
url = 'https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx'
r = s.get(url=url, headers=headers)
# 解析内容,得到验证码图片的src属性
soup = BeautifulSoup(r.text, 'lxml')
image_src = 'https://so.gushiwen.org' + soup.find('img', id='imgCode')['src']
# 将图片下载到本地
# urllib.request.urlretrieve(image_src, 'code.png')
r = s.get(url=image_src, headers=headers)
with open('code.png', 'wb') as fp:
fp.write(r.content)
# 获取表单里隐藏的数据
view_state = soup.find('input', id='__VIEWSTATE')['value']
view_gen = soup.find('input', id='__VIEWSTATEGENERATOR')['value']
return view_state, view_gen
def moni_post(s, view_state, view_gen):
# post的地址
post_url = 'https://so.gushiwen.org/user/login.aspx?from=http%3a%2f%2fso.gushiwen.org%2fuser%2fcollect.aspx'
code = input('请输入验证码:')
# 表单数据
formdata = {
'__VIEWSTATE': view_state,
'__VIEWSTATEGENERATOR': view_gen,
'from': 'http://so.gushiwen.org/user/collect.aspx',
'email': '[email protected]',
'pwd': '123456',
'code': code,
'denglu': '登录',
}
r = s.post(url=post_url, headers=headers, data=formdata)
# 将响应内容写入到文件中
with open('deng.html', 'wb') as fp:
fp.write(r.content)
def main():
# 首先创建一个会话,然后后续的操作都通过这个会话进行,这样就可以保证都是同一个会话了
s = requests.Session()
# 下载验证码到本地
view_state, view_gen = download_image(s)
# 模拟登录
moni_post(s, view_state, view_gen)
if __name__ == '__main__':
main()
注意:只要是有验证码的一定要通过会话操作,通过Session会话来完成
创建一个会话,然后后续操作都通过会话进行,保证在同一次会话当中
s=requests.Session
还要获取表单里面隐藏的数据
view_state = soup.find(‘input’,id=)
view_gen=
要将这两个值给返回,因为这两个参数是在表单里面隐藏的,而且登陆的时候重新写入。
365yg.com 视频下载网站
1.单视频下载
import requests
url = 'http://v11-tt.ixigua.com/1f8fcd093ff8db362348f1ac58c06bec/5b3c86b5/video/m/220c59fd677a39c467798506da24f41a73c1158ad050000077553974abd/'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
}
r = requests.get(url=url, headers=headers)
with open(r'shipin/123我爱你.mp4', 'wb') as fp:
fp.write(r.content)
print('下载成功')
2.多视频下载:
import requests
import time
from bs4 import BeautifulSoup
import json
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')
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
}
def get_video_detail():
'''
url = 'http://365yg.com/'
r = requests.get(url=url, headers=headers)
with open('jinri.html', 'wb') as fp:
fp.write(r.content)
exit()
# 解析之
soup = BeautifulSoup(r.text, 'lxml')
# 提取所有视频页链接
a_list = soup.find_all('a', class_='link')
print(a_list)
print(len(a_list))
'''
# 抓包捕获接口
url = 'http://365yg.com/api/pc/feed/?min_behot_time=0&category=video_new&utm_source=toutiao&widen=1&tadrequire=true&as=A1051B43DC57D41&cp=5B3C87BD8401AE1&_signature=XdHlThAcBu4K5q0VubnD.l3R5V'
# 接口中的widen可以理解为分页,是2的时候就是第二页,以此类推
r = requests.get(url=url, headers=headers)
# 将json格式字符串转化为python对象
obj = json.loads(r.text)
# 得到包含所有视频的列表, 该列表中存放的都是字典
data_list = obj['data']
# 遍历列表,获取字典里面的source_url属性
video_detail_list = []
for data in data_list:
detail_url = 'http://365yg.com' + data['source_url']
video_detail_list.append(detail_url)
return video_detail_list
def download(video_detail_list, browser):
i = 0
# 遍历列表,依次发送请求即可
for detail_url in video_detail_list:
'''
r = requests.get(url=detail_url, headers=headers)
# 生成soup对象,查找video标签,获取src属性即可
soup = BeautifulSoup(r.text, 'lxml')
with open('detail.html', 'wb') as fp:
fp.write(r.content)
# video = soup.find('video')
# print(video)
exit()
'''
i += 1
browser.get(detail_url)
time.sleep(5)
soup = BeautifulSoup(browser.page_source, 'lxml')
video_src = 'http:' + soup.find('video')['src']
# print(video_src)
# exit()
r = requests.get(url=video_src, headers=headers)
filepath = './shipin/' + str(i) + '.mp4'
print('正在下载%s......' % filepath)
with open(filepath, 'wb') as fp:
fp.write(r.content)
print('结束下载%s' % filepath)
time.sleep(2)
def main():
# 让谷歌浏览器以无界面模式启动
path = r'C:\Users\zbli\Desktop\1803\day07\ziliao\chromedriver.exe'
browser = webdriver.Chrome(path, chrome_options=chrome_options)
# 获取到所有的视频页的链接
video_detail_list = get_video_detail()
# 向每一个详情页发送请求,解析内容,得到视频的src,然后下载即可
download(video_detail_list, browser)
browser.quit()
if __name__ == '__main__':
main()