写在前面
对于刚接触爬虫的萌新来说,selenium方式是最友好的,虽然效率不高,但是比人工快,还保护眼睛,因为一开始没有用爬虫的时候,是一个个去人工操作的。 任务来源:其实是我想从一个业务网站下载坐标到本地,建库,方便项目管理,数据质检。 Round 1 一开始没想用selenium,因为效率低。然后下载了相关的软件,把页面分析了断断续续一个月也没找到突破口,因为坐标可能是敏感数据,所以进行了加密。但是导出的时候是可以。 Round 2 后来还特意买了爬虫的书籍来看,有点小题大作,加上书籍内容广泛但不是丰富,其实网上是资源更多,更便捷。研究半天还是决定先用selenium试下,因为着急用数据库成果。
正题
准备工作:安装好谷歌浏览器chorme和对应版本的浏览器驱动chromedriver。 首先要导入需要用到的库
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import pandas as pd
import os
实现路径是: 1.需要把项目清单xls文件导入python,添加做成列表,以便在后面根据调用这个列表进行逐一爬取。(这里我是直接在网上搜索到然后复制修改成自己想要的,还没有完全理解透)
result = []
def excel_one_line_to_list():
df = pd.read_excel("D:\demo\Test_20211116224417原始.xls", usecols=[1],names=None)
df_li = df.values.tolist()
for s_li in df_li:
result.append(s_li[0])
if __name__ == '__main__':
excel_one_line_to_list()
2.调用浏览器驱动打开网页,通过预置的登录账号和密码登录网站()
wd = webdriver.Chrome(r'd:\webdrivers\chromedriver.exe')
wd.implicitly_wait(3)
wd.get('http://XXXX/TdIndex.html')
elements = wd.find_elements_by_xpath("//*[@id='txtLogin']")
element = wd.find_element_by_id("txtLogin")
element.clear()
element.send_keys('qnz')
element = wd.find_element_by_id("txtPass")
element.clear()
element.send_keys('123456\n')
time.sleep(2)
3.登录完成后,跳转到第二个网页,因为登录成功后,页面会刷新到另一个页面,网址是不一样的,此时若不执行跳转,就无法进行下一步操作,因为程序会一直在原来的网址操作,它并不知道已经刷新了新的网址。(知识点:窗口切换)
window_1 = wd.current_window_handle
windows = wd.window_handles
for current_window in windows:
if current_window != window_1:
wd.switch_to.window(current_window)
4.核心代码部分。这部分牵涉到的第一个知识点就是切换框架,因为要操作的元素有在第一级框架,有在第二级框架的,所以需要进入框架、切出框架、回到主页等操作。 第二个知识点就是异常处理。try/except的使用。因为是批量爬取,就会出现有些缺失的情况出现,所以不是所有的操作都能成功,这时候用try/except来处理非常合适。操作结束要关闭窗口,回到第一个窗口,如此循环。
def download(XM_name):
wd.switch_to.frame('frmleft')
wd.find_element(By.ID, 'menu_tree_5_span').click()
wd.switch_to.frame('page_84953F0A-2845-1B2F-B6A6-8ED4854DD400')
wd.switch_to.frame('yb')
wd.find_element(By.NAME, 'ywname').clear()
wd.find_element(By.NAME, 'ywname').send_keys(XM_name)
wd.find_element(By.CLASS_NAME,'icon_find').click()
time.sleep(2)
wd.find_element_by_xpath("//div/a[last()-1]").click()
time.sleep(1)
window_1 = wd.current_window_handle
windows = wd.window_handles
for current_window in windows:
if current_window != window_1:
wd.switch_to.window(current_window)
try:
jie_duan='验收'
wd.find_element_by_xpath('//*[@id="rc_tree"]/li/ul/li[3]/ul/li[3]/div/span[5]').click()
time.sleep(1)
wd.switch_to.frame(1)
wd.find_element_by_xpath('//*[@id="maingrid|2|r1001|c104"]/div/div/a').click()
wd.switch_to.frame('_DialogFrame_0')
wd.find_element_by_xpath('//*[@value=".txt"]').click()
wd.switch_to.parent_frame()
wd.find_element_by_xpath('//*[@id="_ButtonOK_0"]').click()
time.sleep(2)
get(XM_name,jie_duan)
print(XM_name, '---验收坐标下载成功---')
except:
print(XM_name,'---无验收坐标,验收坐标下载失败!---')
try:
jie_duan = '计划'
wd.switch_to.default_content()
wd.find_element_by_xpath('//*[@id="rc_tree"]/li/ul/li[1]/ul/li[3]/div/span[5]').click()
time.sleep(1)
wd.switch_to.frame(2)
wd.find_element_by_xpath('//*[@id="maingrid|2|r1001|c104"]/div/div/a').click()
wd.switch_to.frame('_DialogFrame_0')
wd.find_element_by_xpath('//*[@value=".txt"]').click()
wd.switch_to.parent_frame()
wd.find_element_by_xpath('//*[@id="_ButtonOK_0"]').click()
time.sleep(2)
get(XM_name,jie_duan)
print(XM_name,'---计划坐标下载成功---')
except:
print(XM_name, '---无坐标,下载失败---')
wd.close()
wd.switch_to.window(windows[0])
return
5.上一步调用了一个保存文件的时候对文件进行重命名的函数,因为下载的文件默认已经有名称了,而且下载时并没有重命名的机会,所以需要对下载保存目录下的最新文件进行重命名即可,名称就是从导入的项目名称传递进去即可。(这段代码也是从网上找的,修改了一下就用了)
def get(filename,j_d):
path = r'C:\Users\seawq\Downloads'
list1 = os.listdir(path)
list2 = [x for x in list1 if '.txt' in x]
list2.sort(key=lambda x:os.path.getmtime(path+'\\'+x))
time.sleep(1)
old = os.path.join(path,list2[-1])
new = os.path.join(path,filename+'_'+j_d+'.txt')
os.rename(old,new)
return new
6.最后就是循环调用的部分了。最后关闭窗口,搞定!
i=1
for Nresult in result:
download(Nresult)
i+=1
print(str(i)+'/1709')
print('-------运行完毕-------')
wd.quit()
小结
其实这次用selenium来实现,花时间最多的就是frame(框架)的切换,研究了很久。关于selenium选择元素的方法,学习了css和Xpath,但是现在流行的是Xpath,也相对简单,主流浏览器的检查要素页面都自带提供右键复制Xpath路径和Xpath绝对路径的功能,非常好用,不用你去琢磨应该用ID还是什么来选择,直接复制粘贴到程序里就能用(当然一定要考虑是否有frame,复制的Xpath路径是不考虑frame的,因为我被坑过)。总之对于想学爬虫的初学者来说selenium是非常好的选择,虽然高手都说用selenium来实现不算爬虫,只能说是自动化(seleninum的初衷就是为了做自动化测试的)。
|