目录
3.selenium + phantomjs 强大的网络爬虫组合
day04
- lxml解析库
- 使用流程
- from lxml import etree
- parseHtml = etree.HTML(html)
- parseHtml.xpath('xpath表达式')
- xpath匹配规则
- 获取节点对象://div[@class="Tiger"]
- 获取节点属性值://div[@class="T"]//a/@src
- 函数://div[contains(@class,"a")]//a/@href
- xpath高级
- 基准xpath表达式(节点对象列表)
- for r in [节点对象列表]:
username = parseHtml.xpath('./xpath表达式')
... ...
- 使用流程
day05
1.json模块
- 什么是json?
javascript中的对象和数组
对象:{key:value} 取值:对象名.key
数组:[...,...] 取值:数组[索引值] - 作用
json格式的字符串 和 python数据类型 之间的转换 - 常用方法
- json.loads():json格式 --> Python数据类型
json python
对象 字典
数组 列表'''01_json.loads示例.py''' import json # json格式的数组 jsarray = '[1,2,3,4]' # 数组 -> 列表 L = json.loads(jsarray) print(type(L),L) # json格式对象 jsobj = '{"city":"天地会","name":"步惊云"}' # 对象 -> 字典 D = json.loads(jsobj) print(type(D),D)
- json.dumps():Python数据类型 --> json格式
python json
字典 对象
列表 数组
元组 数组'''02_json.dunps示例.py''' import json L = [1,2,3,4] T = (1,2,3,4) D = {"city":"天地会","name":"聂风"} # python格式 -> json格式 jsarray1 = json.dumps(L) print(type(jsarray1),jsarray1) jsarray2 = json.dumps(T) print(type(jsarray2),jsarray2) jsobj = json.dumps(D,ensure_ascii=False) print(type(jsobj),jsobj)
##注意:- json.dumps()默认使用的是ascii编码
- 添加参数ensure_ascii=False,禁用ascii编码
- json.loads():json格式 --> Python数据类型
2.动态网站数据抓取 - Ajax
- 特点:滚动鼠标滑轮时加载
- 案例:豆瓣电影排行榜数据抓取
- 抓取目标:豆瓣电影 - 排行榜 - 剧情
电影名称,评分 - 代码实现
稍微高级点'''03_豆瓣电影抓取-Ajax.py''' import requests import json import csv num=input('请输入要爬取的数量:') url='https://movie.douban.com/j/chart/top_list' headers={ 'User-Agent':'Mozilla/5.0', } params={ "type":"11", "interval_id":"100:90", "action":'', "start":"0", "limit":num, } res=requests.get(url,params=params,headers=headers) res.encoding='utf-8' # html为json格式的数组[{电影1信息},{},{}] html=res.text html=json.loads(html) #print(html) #用for循环遍历每一个电影信息 with open('豆瓣电影.csv','a',newline='') as f: writer=csv.writer(f) for film in html: name=film['title'] score=film['rating'][0] L=[name,score] writer.writerow(L)
'''03_豆瓣电影抓取-Ajax.py''' import requests import json import csv # url要写抓到的GET :URL url = "https://movie.douban.com/j/chart/top_list?" headers = {"User-Agent":"Mozilla/5.0"} L = ["剧情","喜剧","动作"] tp_list = [{"剧情":"11"},{"喜剧":"24"},{"动作":"5"}] tp = input("请输入电影类型:") if tp in L: num = input("请输入要爬取的数量:") for film_dict in tp_list: for key,value in film_dict.items(): if tp == key: params = { "type":value, "interval_id":"100:90", "action":"", "start":"0", "limit":num } res = requests.get(url,params=params,headers=headers) res.encoding = "utf-8" # html为json格式的数组[{电影1信息},{},{}] html = res.text # 数组 -> 列表 html = json.loads(html) # 用for循环遍历每一个电影信息{} for film in html: name = film['title'] score = film["rating"][0] #{"rating":["9.6","50"],...} with open("豆瓣电影.csv","a",newline="") as f: writer = csv.writer(f) L = [name,score] writer.writerow(L) else: print("您输入的类型不存在!")
- 抓取目标:豆瓣电影 - 排行榜 - 剧情
3.selenium + phantomjs 强大的网络爬虫组合
- selenium
- 定义:Web自动化测试工具,应用于Web自动化测试
- 特点
- 可以运行在浏览器,根据指定命令操作浏览器,让浏览器自动加载页面
- 只是工具,不支持浏览器功能,需要与第三方浏览器结合使用
- phantomjs
- 定义:无界面浏览器(无头浏览器)
- 特点
- 把网站加载到内存进行页面加载
- 运行高效
- 安装
- windows
- 将下载的可执行文件放到Python安装目录的Scripts目录下
在cmd下搜索 where python
然后找到python地址,放到Scripts目录
- 将下载的可执行文件放到Python安装目录的Scripts目录下
- Ubuntu
- 将下载的phantomjs放到一个路径下
- 添加环境变量
vi .bashrc 添加
export PHANTOM_JS=/home/.../phantomjs-2.1.1-...
export PATH=$PHANTOM_JS/bin:$PATH
终端:source .bashrc
终端:phantomjs
- windows
- 示例代码
- 示例代码1:
'''05_phantomjs+selenium示例1.py''' # 导入selenium库中的webdriver接口 from selenium import webdriver # 创建phantomjs浏览器对象 driver = webdriver.PhantomJS() # 发请求 get() driver.get("http://www.baidu.com/") print(driver.page_source) ## 获取网页截屏 #driver.save_screenshot("百度.png") #print("图片保存成功") ## 关闭 #driver.quit()
- 示例代码2:
'''06_phantomjs+selenium示例2.py''' from selenium import webdriver import time # 创建浏览器对象 driver = webdriver.PhantomJS() # 打开页面 driver.get("http://www.baidu.com/") # 发送文字到搜索框 kw = driver.find_element_by_id("kw") kw.send_keys("美女") # 点击 "百度一下" su = driver.find_element_by_id("su") su.click() time.sleep(1) # 获取截屏 driver.save_screenshot("美女.png") # 关闭浏览器 driver.quit()
- 示例代码1:
- 常用方法
- driver.get(url)
打开网站 - driver.page_source:获取响应的html源码
- driver.page_source.find('字符串')
- 作用:从html源码中搜索指定字符串
-1:查找失败
非-1:查找成功
- 作用:从html源码中搜索指定字符串
- 单元素查找
- driver.find_element_by_id(" ").text
- driver.find_element_by_class_name(" ")
- driver.find_element_by_xpath('xpath表达式')
- 如果匹配到多个节点,则只返回第一个节点对象
- 多元素查找
- driver.find_elements_by_...
- 注意
- 如果结果1个,则返回节点对象,不是列表
- 如果结果n个,则返回列表
- 示例
'''08_driver.find查找元素示例.py''' from selenium import webdriver driver = webdriver.Chrome() driver.get("https://www.qiushibaike.com/") # 查找单个节点 element r_One = driver.find_element_by_class_name("content") print(r_One.text) # 查找多个节点 elements r_Many = driver.find_elements_by_class_name("content") for r in r_Many: print(r.text) print() driver.quit()
- 对象名.send_keys("内容")
- 对象名.click()
- driver.get(url)
- 案例1:登录豆瓣网站
'''09_selenium+Chrome登陆豆瓣案例.py''' from selenium import webdriver import time # 创建浏览器对象,发请求 driver = webdriver.Chrome() driver.get("https://www.douban.com/") time.sleep(0.5) # 获取截图(验证码) driver.save_screenshot("验证码.png") # 找 用户名、密码、验证、登陆豆瓣按钮 uname = driver.find_element_by_name("form_email") uname.send_keys("19921510089") # 密码 pwd = driver.find_element_by_name("form_password") pwd.send_keys("zhanshen001") # 验证码 key = input("请输入验证码:") yzm = driver.find_element_by_id("captcha_field") yzm.send_keys(key) driver.save_screenshot("完成.png") # 点击登陆按钮 login = driver.find_element_by_class_name("bn-submit") login.click() time.sleep(1) driver.save_screenshot("登陆成功.png") # 关闭浏览器 driver.quit()
- 操作键盘
- 导模块
from selenium.webdrier.common.keys import Keys - 常用方法
'''10_driver操作键盘示例.py''' from selenium import webdriver # 操作键盘 from selenium.webdriver.common.keys import Keys import time # 创建浏览器对象,发请求 driver = webdriver.Chrome() driver.get("http://www.baidu.com/") # 百度搜索框输入python kw = driver.find_element_by_id("kw") kw.send_keys("python") driver.save_screenshot("01_python.png") # 全选 :Ctrl + a kw = driver.find_element_by_id("kw") kw.send_keys(Keys.CONTROL,'a') driver.save_screenshot("02_CtrlA.png") # 剪切 :Ctrl + x kw = driver.find_element_by_id("kw") kw.send_keys(Keys.CONTROL,'x') driver.save_screenshot("03_CtrlX.png") # 粘贴 :Ctrl + v kw = driver.find_element_by_id("kw") kw.send_keys(Keys.CONTROL,'v') driver.save_screenshot("04_CtrlV.png") # 清空搜索框 : 对象名.clear() kw = driver.find_element_by_id("kw") kw.clear() driver.save_screenshot("05_Clear.png") # 输入 :达内科技 kw = driver.find_element_by_id("kw") kw.send_keys("达内科技") driver.save_screenshot("06_Tarena.png") # 输入 :回车 kw = driver.find_element_by_id("kw") kw.send_keys(Keys.ENTER) time.sleep(1) driver.save_screenshot("07_Enter.png") # 关闭浏览器 driver.quit()
- 导模块
- 案例2:斗鱼直播网站主播信息抓取
- 抓取目标:主播名称,观众人数
- 主播:class -- dy-name ellipsis fl
//div[@id="live-list-content"]//span[@class="dy-name ellipsis fl"] - 人数:class -- dy-num fr
//div[@id="live-list-content"]//span[@class="dy-num fr"] - 下一页按钮(能点的按钮):class -> shark-pager-next
- 下一页按钮(不能点的按钮):
- 主播:class -- dy-name ellipsis fl
- 代码实现
'''11_斗鱼直播抓取案例.py''' from selenium import webdriver from lxml import etree import time # 把Chrome设置无界面浏览器 opt = webdriver.ChromeOptions() opt.set_headless() # 创建浏览器对象,发请求 driver = webdriver.Chrome(options=opt) driver.get("https://www.douyu.com/directory/all") i = 1 # 循环 while True: # 解析(driver.page_source) # 获取主播名称 和 观众人数 parseHtml = etree.HTML(driver.page_source) names = parseHtml.xpath('//div[@id="live-list-content"]//span[@class="dy-name ellipsis fl"]') numbers = parseHtml.xpath('//div[@id="live-list-content"]//span[@class="dy-num fr"]') for name,number in zip(names,numbers): print("\t主播名称:%s \t观众人数:%s" % (name.text.strip(),number.text.strip())) #for name,number in [("主播1","20万"),("主播2","15万")] print("第%d页爬取成功" % i) i += 1 # 判断是否需要点击下一页 # 能点 :点击,继续循环 if driver.page_source.find("shark-pager-disable-next") == -1: driver.find_element_by_class_name("shark-pager-next").click() time.sleep(1) else: break # 不能点 :break print("一共爬取了%d页" % i)
- 抓取目标:主播名称,观众人数
- Chromdriver如何设置无界面模式
1、opt = webdriver.ChromeOptions()
2、opt.set_headless()
3、driver = webdriver.Chrome(options=opt)
4、driver.get(url) - 案例3:京东商品爬取
- 目标
- 商品名称
- 商品价格
- 评论数量
- 商家名称
- 代码实现
'''12_京东商品爬取.py''' from selenium import webdriver import time import csv # 接受用户输入,访问京东 pro = input("请输入要爬取的商品:") driver = webdriver.Chrome() driver.get("https://www.jd.com/") i = 1 # 发送文字到搜索框,点击搜索 text = driver.find_element_by_class_name("text") text.send_keys(pro) button = driver.find_element_by_class_name("button") button.click() time.sleep(1) while True: # 动态加载-->全部加载 # 执行脚本,进度条拉到底部 driver.execute_script( 'window.scrollTo(0,\ document.body.scrollHeight)') time.sleep(2) # 正常解析爬取 r_list = driver.find_elements_by_xpath\ ('//div[@id="J_goodsList"]//li') # r为每一个商品的节点对象 for r in r_list: m = r.text.split('\n') # ["¥52.80","Python...","200+",] if m[1] != "拍拍": price = m[0] name = m[1] commit = m[2] market = m[3] else: price = m[0] name = m[2] commit = m[3] market = "拍拍" with open("商品.csv","a",newline="",encoding="gb18030") as f: writer = csv.writer(f) L = [name.strip(),price.strip(), commit.strip(),market.strip()] writer.writerow(L) print("第%d页爬取成功" % i) i += 1 # 点击下一页 if driver.page_source.find("pn-next disabled") == -1: driver.find_element_by_class_name("pn-next").click() time.sleep(1) else: print("抓取结束,共抓取%d页" % i) break
-
小提示:
JS控制滚动条的位置:
window.scrollTo(x,y);竖向滚动条置顶(window.scrollTo(0,0);
竖向滚动条置底 window.scrollTo(0,document.body.scrollHeight)
当前窗口driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')
- 目标
今日示例