在 Selenium python 中包含某些文本的其他 div 中选择某些 div 的方法
Posted
技术标签:
【中文标题】在 Selenium python 中包含某些文本的其他 div 中选择某些 div 的方法【英文标题】:Way to select certain div among other divs that contains certain text in Selenium python 【发布时间】:2020-11-08 18:45:33 【问题描述】:我正在使用 selenium 给我在军队的朋友写一封在线信。该网站不提供 API 或任何东西。 我的很多朋友都在军队里,我想选择把信寄给谁。 从现在开始,假设我朋友的名字是霍华德。
选择页面是这样的
每个朋友都有自己的卡片式 div,他们都共享同一个类(cafe-card-box),没有 id 或名称。
所有的 div 都在滑块中,这是可怕的编码。出于某种原因,div 被无形地复制了好几次。只有霍华德有 2-3 个 div。
不同用户的 div 顺序不同。
士兵的名字在 cafe-card-box(class) -> flex(class) -> profile-wrap(class) -> id(class) -> span(tag only) 中。除了 .
中的内容外,所有 div 都相同一些随机空白文本共享 class="id"。而跨度标签不仅有名字,还有士兵在军队服役的时间是这样的:
Jacob(来了 2 周)
初步方法
最初,我写了这段代码:
cafes = self.driver.find_elements_by_class_name("cafe-card-box")
for cafe in cafes:
cf_name = cafe.find_element_by_class_name("id").text[0:3] #Almost every Korean names are 3 characters.
if cf_name == soldier_name:
print("found.")
cafe.find_element_by_link_text("위문편지").click()
break
else:
print("It's not the one. Moving to the next ID class.")
只要名称在 div 中的某处,就可以按预期工作。问题是即使名称错误,程序也需要工作。我后来尝试了这段代码:
while n<=len(cafes):
n = n + 1
try:
for cafe in cafes:
cf_name = cafe.find_element_by_class_name("id").text[0:3]
if cf_name == soldier_name:
print("Found!")
cafe.find_element_by_link_text("위문편지").click()
ps(3)
break
except:
print("Can't find anyone.")
self.driver.quit()
quit()
这完全没有用。回想起来,实际工作的第一个代码看起来一点也不合法。我现在想遍历每个卡片 div,查找名称是否匹配,如果匹配则将框架更改为它,然后单击该特定 div 中的按钮。
这可能吗?如果有怎么办?我觉得我什么都试过了。
附带问题
有没有更好的方法来提取名字?
cafe.find_element_by_class_name("id").text[0:3]
这似乎不太专业。所有名称均以 1 个空格分隔。
编辑
添加 html 代码。
<div class="group">
<div class="section-title bd_gradation">
<strong class="title">내 카페 <em>(2)</em></strong>
</div>
<div class="swiper-container cafe-slide-wrap swiper-container-horizontal" id="divSlide1">
<div class="swiper-wrapper" style="transition-duration: 0ms; transform: translate3d(-1140px, 0px, 0px);"><div class="swiper-slide swiper-slide-duplicate swiper-slide-duplicate-active swiper-slide-prev" data-swiper-slide-index="0">
<!-- cafe-card-box -->
<div class="cafe-card-box">
<div class="flex">
<div class="photo-wrap" onclick="javascript:fn_selectListPost(1,'20121590200','4737','0000140002');" style="cursor: pointer;">
<script>
var filedata =
fileTypeCd : "0000210002"
,thumb : thumbSizeMgr.unitMark
,filePath : "/images/upload/20191122/nb3705@naver.com/"
,savedFileNm : "20191122092608029_ge1"
,extNm : "jpg"
;
document.write('<img src="'+fn_getFileSrcUrl(filedata)+'" >');
</script><img src="./카페 메인_files/20191122092608029_ge1.jpg" >
</div>
<div class="profile-wrap" onclick="javascript:fn_compMain('4737','20121590200');" style="cursor: pointer;">
<div class="id"><!-- 최대 2줄 -->
<span>NAME CENSORED (입영 2주차)</span>
</div>
<div class="cafe-sh-txt"><!-- 최대 2줄 -->
PRIVATE INFO CENSORED
</div>
<div class="cafe-sh-date"><!-- 최대 2줄 -->
<span>입영일 <em> 2020.07.06 </em></span>
<span>수료일 <em> 2020.08.12 </em></span>
</div>
</div>
</div>
<div class="btn-wrap">
<a href="javascript:fn_consolLetter('4737','20121590200');" class="btn-green">위문편지</a>
<a href="javascript:fn_compMain('4737','20121590200');" class="btn-blue">카페바로가기</a>
</div>
</div>
<!-- //cafe-card-box -->
<div class="cafe-card-box">
<div class="flex">
<div class="photo-wrap" onclick="javascript:fn_selectListPost(1,'20020191700','4727','0000140001');" style="cursor: pointer;">
<script>
var filedata =
fileTypeCd : "0000210002"
,thumb : thumbSizeMgr.unitMark
,filePath : "/images/upload/20200227/1234/"
,savedFileNm : "20200227104858343_ge1"
,extNm : "png"
;
document.write('<img src="'+fn_getFileSrcUrl(filedata)+'" >');
</script><img src="./카페 메인_files/20200227104858343_ge1.png" >
</div>
<div class="profile-wrap" onclick="javascript:fn_compMain('4727','20020191700');" style="cursor: pointer;">
<div class="id"><!-- 최대 2줄 -->
<span>NAME CENSORED (입영 2주차)</span>
</div>
<div class="cafe-sh-txt"><!-- 최대 2줄 -->
PRIVATE INFO CENSORED
</div>
<div class="cafe-sh-date"><!-- 최대 2줄 -->
<span>입영일 <em> 2020.07.06 </em></span>
<span>수료일 <em> 2020.08.11 </em></span>
</div>
</div>
</div>
<div class="btn-wrap">
<a href="javascript:fn_consolLetter('4727','20020191700');" class="btn-green">위문편지</a>
<a href="javascript:fn_compMain('4727','20020191700');" class="btn-blue">카페바로가기</a>
</div>
</div>
<!-- //cafe-card-box -->
</div>
<div class="swiper-slide swiper-slide-active swiper-slide-duplicate-next swiper-slide-duplicate-prev" data-swiper-slide-index="0">
<!-- cafe-card-box -->
<div class="cafe-card-box">
<div class="flex">
<div class="photo-wrap" onclick="javascript:fn_selectListPost(1,'20121590200','4737','0000140002');" style="cursor: pointer;">
<script>
var filedata =
fileTypeCd : "0000210002"
,thumb : thumbSizeMgr.unitMark
,filePath : "/images/upload/20191122/nb3705@naver.com/"
,savedFileNm : "20191122092608029_ge1"
,extNm : "jpg"
;
document.write('<img src="'+fn_getFileSrcUrl(filedata)+'" >');
</script><img src="./카페 메인_files/20191122092608029_ge1.jpg" >
</div>
<div class="profile-wrap" onclick="javascript:fn_compMain('4737','20121590200');" style="cursor: pointer;">
<div class="id"><!-- 최대 2줄 -->
<span>NAME CENSORED (입영 2주차)</span>
</div>
<div class="cafe-sh-txt"><!-- 최대 2줄 -->
PRIVATE INFO CENSORED
</div>
<div class="cafe-sh-date"><!-- 최대 2줄 -->
<span>입영일 <em> 2020.07.06 </em></span>
<span>수료일 <em> 2020.08.12 </em></span>
</div>
</div>
</div>
<div class="btn-wrap">
<a href="javascript:fn_consolLetter('4737','20121590200');" class="btn-green">위문편지</a>
<a href="javascript:fn_compMain('4737','20121590200');" class="btn-blue">카페바로가기</a>
</div>
</div>
<!-- //cafe-card-box -->
<!-- cafe-card-box -->
<div class="cafe-card-box">
<div class="flex">
<div class="photo-wrap" onclick="javascript:fn_selectListPost(1,'20020191700','4727','0000140001');" style="cursor: pointer;">
<script>
var filedata =
fileTypeCd : "0000210002"
,thumb : thumbSizeMgr.unitMark
,filePath : "/images/upload/20200227/1234/"
,savedFileNm : "20200227104858343_ge1"
,extNm : "png"
;
document.write('<img src="'+fn_getFileSrcUrl(filedata)+'" >');
</script><img src="./카페 메인_files/20200227104858343_ge1.png" >
</div>
<div class="profile-wrap" onclick="javascript:fn_compMain('4727','20020191700');" style="cursor: pointer;">
<div class="id"><!-- 최대 2줄 -->
<span>NAME CENSORED (입영 2주차)</span>
</div>
<div class="cafe-sh-txt"><!-- 최대 2줄 -->
PRIVATE INFO CENSORED
</div>
<div class="cafe-sh-date"><!-- 최대 2줄 -->
<span>입영일 <em> 2020.07.06 </em></span>
<span>수료일 <em> 2020.08.11 </em></span>
</div>
</div>
</div>
<div class="btn-wrap">
<a href="javascript:fn_consolLetter('4727','20020191700');" class="btn-green">위문편지</a>
<a href="javascript:fn_compMain('4727','20020191700');" class="btn-blue">카페바로가기</a>
</div>
</div>
<!-- //cafe-card-box -->
</div>
【问题讨论】:
您能否在您的问题中添加一些 HTML 来说明您正在处理的标记结构? @GregBurghardt 我已经添加了代码。一开始我尽量不这样做,因为它看起来太复杂了。 您是否也可以通过创建一个最小示例来尽量减少问题的长度?我相信它会帮助其他人给你最好的解决方案:-) 【参考方案1】:您可以找到所有包含特定文本的 div 元素:
from selenium import webdriver
driver = webdriver.Chrome()
# Some code...
divList = [div for div in driver.find_elements_by_tag_name('div') if 'The text to find' in div.get_attribute('innerText')]
【讨论】:
【参考方案2】:不知道这是否对你有用,但你也可以使用 XPATH,像这样:
from selenium import webdriver
driver = webdriver.Chrome()
# Some code...
elementList = driver.find_elements_by_xpath('//div[contains(@class,"profile-wrap")]/div[@class="id"]/span[contains(text(),'NAME')]')
请注意以下事实:
XPATH 是最慢的“find_”方法,如果您别无选择或项目不太关心性能,请使用它 XPATH 无法执行不区分大小写的搜索,因此您必须进行翻译(参见此处https://***.com/a/8474109/3228768),并且可能不适合您需要查找的字符 XPATH 可以轻松地选择将/..
附加到查询的祖先
注意:
-
如您所见,我使用了两种不同的条件来按类定位 div。一个是带有 contains() 的,另一个是没有它的。不同之处在于,在第二种形式中,只有当目标具有类名作为“类”属性的唯一值时,才会匹配目标。
您可以从 xpath 返回的元素中提取文本以获得可靠的文本提取
【讨论】:
以上是关于在 Selenium python 中包含某些文本的其他 div 中选择某些 div 的方法的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 JUnit 断言元素包含 Selenium 中的文本