selenium 爬取ajax动态网页

公司用了一个投票网站调查了一些用户的相关信息,但是天呐个撸的调查信息中的 接受调查者的 地址信息居然不能 下载,没有办法只能爬虫了

 

分析发现这是一个ajax动态网页,通过各种抓包,各种分析网页结构就是不能发现这个post提交的参数出现规律

 

 

没有办法,只能通过 selenium模拟人工进行操作了,代码如下:

import json
import os
import re
from urllib.parse import urlencode  #Python内置的HTTP请求库
import requests
from bs4 import BeautifulSoup
from selenium import webdriver
import time
import pandas as pd
from selenium.webdriver.common.keys import Keys
from tqdm import *
from urllib import request
from selenium.webdriver.common.action_chains import ActionChains #导入控制鼠标事件的方法
import warnings
warnings.filterwarnings("ignore")



def loginSys(username, password):
	'''
    登陆
    利用webdriver驱动打开浏览器,操作页面
    此处使用火狐浏览器
    '''
	print('开始登陆')
	target = 'https://www.mikecrm.com/login.php'
	driver = webdriver.Chrome()
	driver.get(target)
	driver.implicitly_wait(0.1)
	LoginTitle = driver.title


	result = driver.title
	if LoginTitle == result:
		driver.find_element_by_name('account').send_keys(username)  # 找到用户名录入框并填写
		time.sleep(0.2)  # 停顿模拟真实操作情况,降低被网站发现的几率
		driver.find_element_by_name('password').send_keys(password)  # 找到输入密码录入框并填写

		driver.implicitly_wait(10)
		driver.find_element_by_class_name("cp_btnWithLoading").click()  # 点击登录 class名字如果 有空格话 取前半段 或任一部分都行

		driver.implicitly_wait(10)
		print('进入第二个页面')
		time.sleep(0.2)
		# input('跳入到第三个页面?')
		time.sleep(2)
		driver.find_element_by_xpath("//*[@data-reactid='.0.1.0.2.0.$hform.0.2']").click()
		print('已经跳入到第三个页面')
		# input('跳入到第四个页面?')
		time.sleep(0.5)
		driver.find_element_by_xpath("//*[@data-reactid='.0.2.$=1$normal/=010.0.1.$frgr200004615']").click()
		print('已经跳入到第四个页面')
		# input('跳入到第五个页面?')
		time.sleep(0.5)
		#快递员调查问卷
		driver.find_element_by_xpath("//*[@href='#/submit?id=200077139']").click()
		print('已经跳入到(最后一个)第五个页面')

	
		sniffData(driver)
		# 抓取数据完毕关闭浏览器
		time.sleep(0.2)
		# 最后关闭浏览器

		driver.close()



def sniffData(driver): #在解析网页之前需要先 等待一下 否则 解析出的将是登录页
	'''这个函数用来对解析出来的源代码进行解读'''
	count_ =[]


	list_ = []
	#快递员调查问卷
	target = 'https://www.mikecrm.com/form.php#/submit?id=200077139'
	# 速递易用户调查问卷
	# target = 'https://www.mikecrm.com/form.php#/submit?id=200079184'
	time.sleep(1)
	driver.get(target)
	html = driver.page_source

	data = BeautifulSoup(html, "lxml")
	a = [i.contents[0] for i in data.find_all(class_='fbl_sysInfo')]
	b = [i.contents[0] for i in data.select('span[data-reactid$=".1:$comAns0.1"]')]
	c = [i.contents[0] if i.contents!=[] else '无' for i in data.find_all(class_='fbl_itemInfo') ]
	#[0] if i.contents[0]!='' else '空'
	print('a:',len(a),a)
	print('b:',len(b),b)
	print('c:',len(c),c)
	count_.append({'a':len(a),'b':len(b),'c':len(c)})
	for i in range(int(len(a)/4)):
		list_new_first = a[i*4:i*4+4]
		list_new_first += b[i*3:i*3+3]
		list_new_first += c[i * 2:i * 2 + 2]
		list_ += list_new_first


	print(list_)

	# input('阻塞在这里')

	# 快递员调查问卷
	driver.find_element_by_xpath("//*[@data-reactid='.0.2.$=1$submit/=010.$fbList.0.2.2.0.$scrollContent.0:0:$feedback208109767.0.1.$liItemsubmitLocation.1']").click()
	# 速递易用户调查问卷
	# driver.find_element_by_xpath("//*[@data-reactid='.0.2.$=1$submit/=010.$fbList.0.2.2.0.$scrollContent.0:0:$feedback208707069.0.1.$liItemsubmitLocation.1']").click()

	Action = ActionChains(driver)
	for i in tqdm(range(200)):
		Action.key_down(Keys.ARROW_DOWN ,element=None).perform()
		# driver.execute_script("var q=document.body.scrollTop={}".format(i*100))

		time.sleep(3)
		driver.get(target)
		html = driver.page_source
		data = BeautifulSoup(html, "lxml") #lxml解析器较快
		a = [i.contents[0] for i in data.find_all(class_='fbl_sysInfo')]
		b = [i.contents[0] for i in data.select('span[data-reactid$=".1:$comAns0.1"]')]
		c = [i.contents[0] if i.contents != [] else '无' for i in data.find_all(class_='fbl_itemInfo')]
		count_.append({'a': len(a), 'b': len(b), 'c': len(c)})
		for i in range(int(len(a) / 4)):
			list_new_first = a[i * 4:i * 4 + 4]
			list_new_first += b[i * 3:i * 3 + 3]
			list_new_first += c[i * 2:i * 2 + 2]
			list_ += list_new_first

	else:
		list_1 = []

		for i in range(0,len(list_)-9,9): #先将列表中的内容变成一个个字典
			dict_ = {}
			list_new = list_[i:i + 9]
			if list_new[0] == '#26':
				break
			dict_['序号'] = list_new[0]
			dict_['提交时间'] = list_new[1]
			dict_['提交地点'] = list_new[2]
			dict_['全局编号'] = list_new[3]

			dict_['投件中遇到最多的机柜问题是哪些'] = list_new[4]
			dict_['遇到问题希望通过什么样的方式来解决?'] = list_new[5]
			dict_['投件中遇到最多的App使用问题是哪些'] = list_new[6]
			dict_['其他使用速递易机柜您最想吐槽的问题'] = list_new[7]
			dict_['用户反映到您这最多的一些问题是哪些?'] = list_new[8]

			list_1.append(dict_)
		list_2 = []
		for i in list_1:                   #再对这些列表去重
			if i not in list_2:
				list_2.append(i)
		# if os.path.exists(r'C:\Users\lenovo\Desktop\test2.xlsx'):  # 判断文件是否存在
		# 	os.remove(r'C:\Users\lenovo\Desktop\test2.xlsx')  # 如果存在文件则删除
		total_data = pd.DataFrame(list_2)
		total_data['标识符'] = total_data['序号'].map(lambda x:int(str(x)[1:]))
		total_data = total_data.reset_index().set_index('标识符').sort_index()
		total_data.drop(labels=['index'],axis=1,inplace=True)
		total_data.to_excel(r'C:\Users\lenovo\Desktop\test2.xlsx')
		pd.DataFrame(count_).to_excel(r'C:\Users\lenovo\Desktop\count_.xlsx')
		print(len(total_data))



		input('阻塞在这里了')






if __name__ == "__main__":

	username = "xxxxxxx"
	password = "xxxxxxx"
	loginSys(username, password)






实现结果如下:

爬完数据发现这个数据有缺失值,一共4600条数据,大概缺失500条左右,缺失原因是 我是通过 一直按住  向下键不松  直到卡住才下一次循环,但是 beautifulsoup一次只能解析出 40条信息,如果一次加载过多的话,就会有一些信息没有被解析出来,就会遗失,有两种解决方法,一种是一次只加载40条(可以通过右边的滚动条下拉40条信息的长度,但是我在我这里没有试验成功,在其他人那里可以,这个接下来再研究研究),另一种是继续深入研究这个ajax加载数据的,分析这个post提交的参数,通过模拟ajax反馈出来的信息来解析。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值