爬虫1.5-ajax数据爬取
爬虫-ajax数据爬取
1. ajax数据
ajax (异步JavaScript 和 XML)(读作阿贾克斯),ajax可以时网页实现异步更新,一般使用的json数据交互,即在不重新加载整个页面也可以对网页的部分进行更新,ajax技术加载的数据在网页源代码中是看不到的,只能看到url加载的html部分
获取ajax数据的两种方式
1 分析ajax调用的接口,发现url的参数,再通过代码请求这个接口,直接拿到json数据,有时json数据可能是加密的,或者发送post请求获取json数据并且表单中的数据是按照一定规则写的,这时需要分析js代码,就很麻烦了。
2 Selenium+chromedriver 获取动态数据,Selenium 相当于可以模拟输入、删除和点击操作以及cookie chromedriver是一个驱动chrome浏览器的驱动程序,使用它可以驱动浏览器。这种方式可以直接获取网页中全部的代码,包括ajax技术加载的数据。例如有的网站点击“更多”按钮后可以加载的数据,将全部被获取。虽然这种方式简单粗暴,但每次请求页面时都会打开一个页面,加载数据和渲染页面,显得过于笨重。
2. selenium+chromedriver知识准备
chromedriver是谷歌浏览器的驱动程序,使用selenium可以操作它
chromedriver.exe需要放在一个非中文目录下
2.1 selenium+chromedriver简单操作
form selenium import webdriver
driver_path = r'D:\chromedriver\chromedriver.exe' # 指明路径
driver = webdriver.Chrome(executable_path=driver_path) # 创建driver实例,将路径传入
driver.get("https://www.baidu.com") # get方式打开百度,注意一定要加https:// 否则会报错
driver.page_source # 获取源代码,然后可以扔给正则表达式或者xpath解析,这里可以直接获取ajax数据
driver.close() #关闭一个页面
driver.quit() #关闭整个浏览器
2.2 常用表单元素
input type='text/password/email/number' 文本框
button input [type='submit'] 按钮 例如登陆
checkbox input type='checkbox' 例如记住密码选项
select 下拉菜单
2.3 模拟点击
driver.get('https://www.douban.com/')
remenberBtn = driver.find_element_by_id('form_remember')
remenberBtn.click()
2.4 行为链
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains #导入driver和行为链类
driver_path = r'D:\chromedriver\chromedriver.exe' #指定路径
driver = webdriver.Chrome(executable_path=driver_path) #创建对象
driver.get('https://www.qq.com/') #打开网页
moveTag = driver.find_element_by_xpath("//div[@class='more-txt']") #定位腾讯网中“更多”按钮
clickTag = driver.find_element_by_xpath("//ul[@class='sub-list cf']/li[1]")
#定位“独家”按钮
actions =ActionChains(driver) # 创建行为链对象
actions.move_to_element(moveTag) # 移动到定位点
actions.click(moveTag) # 点击 好像不点击也可以
actions.move_to_element(clickTag) # 移动到”独家“按钮
actions.click(clickTag) # 点击
actions.perform() # 必须调用的函数 否则不会执行之前定义好的行为
# drver.find_element_by_xpath("") 意味着可以使用xpath语法找到想要点击的按钮或输入框
# 类似的还有id class css
2.5 页面等待
1 隐式等待
driver.implicitly_wait(x) # x是等待时间 x秒
2 显示等待
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver_path = r'D:\chromedriver\chromedriver.exe'
driver = webdriver.Chrome(executable_path=driver_path)
driver.get('https://new.qq.com/ch/ori/')
try:
WebDriverWait(driver, 10).until(
# 这里使用WebDriverWait类填入参数 10代表等待10s未出现则抛出异常
EC.presence_of_element_located((By.CLASS_NAME, 's '))
#这里就是等待条件 即当class属性=s 被加载后条件达成
)
finally:
print("2222") # 这样的话当没有等待到期望的条件就可以做其他事情
2.6 窗口
打开多个窗口
driver.get('https://new.qq.com/ch/ori/')
driver.execute_script("window.open('https://www.douban.com/')")
#使用JavaScript脚本打开新页面
driver.get('https://new.qq.com/ch/ori/')
driver.execute_script("window.open('https://www.douban.com/')") # 打开两个页面
print(driver.current_url) # 打印当前url
driver.switch_to.window(driver.window_handles[1]) # 切换窗口 窗口列表中第二个窗口的索引是1
print(driver.current_url) # 打印当前url
2.7 代理ip
driver_path = r'D:\chromedriver\chromedriver.exe'
options = webdriver.ChromeOptions() # 创建配置对象
options.add_argument("--proxy-server=http://221.6.32.206:41816") # 写入配置
driver = webdriver.Chrome(executable_path=driver_path, options=options) # 写入参数
driver.get('https://www.baidu.com/s?wd=ip')
3. selenium+chromedriver实战拉勾网爬虫代码
# 拉勾网的反爬太恶心了,于是用selenium+chromedriver来爬,结果还是被封了,我去
import re
import time
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from lxml import etree
class LagouSpider(object):
def __init__(self):
driver_path = r'D:\chromedriver\chromedriver.exe' # 指定chromedriver 的路径
self.driver = webdriver.Chrome(executable_path=driver_path)
self.base_url = 'https://www.lagou.com/jobs/list_python?px=default&city=%E6%88%90%E9%83%BD#filterBox' # 拉勾网搜索python的页面url
self.data = [] # 用来存放字典
def get_url_list(self):
while True:
self.driver.get(self.base_url) # 访问拉勾网
# 获取页面全部文本信息,这里可以直接获取ajax技术返回的数据,
# 如果用requests库需要找到发送json请求的数据包
text = self.driver.page_source
try:
# 等待职位信息的url出现,timeout=3s
WebDriverWait(self.driver, 3).until(
EC.presence_of_element_located((By.CLASS_NAME, 'position_link'))
)
# 获取url并调用get_info函数
url_list = re.findall(r'<a class="position_link" href="(.*?)" target=.*?>', text, re.S)
for i in url_list:
self.get_info(i)
finally:
# 判断是否已到最后一页
if len(re.findall(r'class="pager_next pager_next_disabled"', text, re.S)) != 0:
self.driver.quit()
break
# 找到下一页的位置并点击
else:
nextPageTag = self.driver.find_element_by_xpath("//div[@class='pager_container']/span[last()]")
nextPageTag.click()
def get_info(self, url):
# 打开新窗口,移动driver,不移动无法获取page_source
self.driver.execute_script("window.open('{}')".format(url))
self.driver.switch_to.window(self.driver.window_handles[1])
try:
# 提取信息,因为职位描述信息的标签实在是太乱了,还是用xpath舒服一点
html = etree.HTML(self.driver.page_source)
work_name = re.findall(r'<div class="job-name" title="(.*?)">', self.driver.page_source, re.S)[0]
salary = re.findall(r'<span class="salary">(.*?)</span>', self.driver.page_source, re.S)[0]
# 获取职位描述信息
temp = html.xpath("//dd[@class='job_bt']//div/p/text()")
describe = ''
for i in temp:
describe += i
describe = re.subn(r'\s*', '', describe)
temp = {
'job_name': work_name,
'describe': describe[0],
'salary': salary
}
print(temp)
# 放入列表中,方便写入csv或者txt
self.data.append(temp)
except:
# 出错的页面打印出来
print(url)
time.sleep(5)
finally:
# 关闭页面,移动driver到最开始的base_url
self.driver.close()
self.driver.switch_to.window(self.driver.window_handles[0])
time.sleep(1)
def run(self):
self.get_url_list()
if __name__ == '__main__':
spider = LagouSpider()
spider.run()
爬虫1.5-ajax数据爬取的更多相关文章
- python-day7爬虫基础之Ajax数据爬取
前几天一直在忙老师的项目,就没有继续学python,也没有写什么收获,今天晚上有空看看书,边看边理解着写吧: 首先说一下,我对Ajax的理解,就是有时候我们在浏览某个网页的时候,只要我们鼠标一直往下滑 ...
- 爬虫(十):AJAX、爬取AJAX数据
1. AJAX 1.1 什么是AJAX AJAX即“Asynchronous JavaScript And XML”(异步JavaScript和XML)可以使网页实现异步更新,就是不重新加载整个网页的 ...
- Ajax数据爬取
Ajax的基本原理 以菜鸟教程的代码为例: XMLHTTPRequest对象是JS对Ajax的底层实现: var xmlhttp; if (window.XMLHttpRequest) { // IE ...
- 爬虫—Ajax数据爬取
一.什么是Ajax 有时候我们使用浏览器查看页面正常显示的数据与使用requests抓取页面得到的数据不一致,这是因为requests获取的是原始的HTML文档,而浏览器中的页面是经过JavaScri ...
- 第十四节:Web爬虫之Ajax数据爬取
有时候在爬取数据的时候我们需要手动向上滑一下,网页才加载一定量的数据,但是网页的url并没有发生变化,这时我们就要考虑使用ajax进行数据爬取了...
- Ajax数据爬取--爬取微博
Ajax Ajax,即异步的JaveScript和XML.它不是一门编程语言,而是利用JaveScript在保证页面不被刷新,页面链接不改变的情况下与服务器交换数据并更新部分网页的技术. 对于传统的网 ...
- python爬虫-上期所持仓排名数据爬取
摘要:笔记记录爬取上期所持仓数据的过程,本次爬取使用的工具是python,使用的IDE是pycharm 一.查看网页属性,分析数据结构 在浏览器中打开上期所网页,按F12或者选择表格文字-右键-审查元 ...
- 前端反爬虫策略--font-face 猫眼数据爬取
1 .font-face定义了字符集,通过unicode去印射展示. 2 .font-face加载网络字体,我么可以自己创建一套字体,然后自定义一套字符映射关系表例如设置0xefab是映射字符1, ...
- [Python3网络爬虫开发实战] 6-Ajax数据爬取
有时候我们在用requests抓取页面的时候,得到的结果可能和在浏览器中看到的不一样:在浏览器中可以看到正常显示的页面数据,但是使用requests得到的结果并没有.这是因为requests获取的都是 ...
- Python3.6爬虫+Djiago2.0+Mysql --数据爬取
1.下载对应版本的python mysql 模块 我的是:pymssql-2.2.0.dev0-cp36-cp36m-win_amd64.whl 2.手动创建table create table gr ...
随机推荐
- STC12LE5620AD RAM问题
1.此款单片机内部有 sram:768B=512B(aux)+256B(Internal) 2.内部RAM解析 2. 3.内部扩展RAM 4.keil中可以选择内存类型 5. 网上摘抄的一段话: 在S ...
- CSS3-transition常用属性及示例
transition参数 语法 transition: property duration timing-function delay transition属性是个复合属性,她包括以下几个子属性: t ...
- GoBelieve IM 服务端编译
#部署im1. 安装go编译环境参考链接:https://golang.org/doc/install 2. 下载im_service代码 cd $GOPATH/src/github.com/GoBe ...
- Web项目开发中常见安全问题及防范
计算机程序主要就是输入数据 经过处理之后 输出结果,安全问题由此产生,凡是有输入的地方都可能带来安全风险.根据输入的数据类型,Web应用主要有数值型.字符型.文件型. 要消除风险就要对输入的数据进行检 ...
- ATM购物作业
一. 基本需求 模拟实现一个ATM + 购物商城程序 额度 15000或自定义 实现购物商城,买东西加入 购物车,调用信用卡接口结账 可以提现,手续费5% 支持多账户登录 支持账户间转账 记录日常消费 ...
- vue中将html字符串转换成html后的一些问题
今天整理之前做vue项目时遇到的一些问题,发现了当时遇到的一个很小但是又会引出很多问题的一个问题(总之就是很有意思,听我慢慢给你到来),这个问题就是当时处理后端数据时,如何将后端返回来的字符串转换成h ...
- python打印九九乘法表
每种编程语言都可能会遇到编写“九九乘法表”的问题,用Python来处理也是很简单的,具体代码如下(基于Python3)): i = 1 while i <= 9: j = 1 while j & ...
- python3 package management 包管理 实例
包是一种组织管理代码的方式,包里面存放的是模块 用于将模块包含在一起的文件夹就是包 包内包含__init__.py标志性文件 定义一个学生类,一个sayhello函数,一个打印语句 # p01.py ...
- c语言中:strlen和sizeof的区别和它们分别交换各自作用领域(\0问题)时的细微差别!!!
本人c语言初学菜鸟一枚,今天通过敲了一段简单代码,发现strlen和sizeof之间的一些关系,总结如下: 用strlen计算数组长度要考虑进去\0 用sizeof计算字符串长度也要考虑进去\0 而s ...
- 中国大学MOOC-C程序设计(浙大翁恺)—— 时间换算
时间换算(10分) 题目内容: UTC是世界协调时,BJT是北京时间,UTC时间相当于BJT减去8.现在,你的程序要读入一个整数,表示BJT的时和分.整数的个位和十位表示分,百位和千位表示小时.如果小 ...