python selenium根据子元素查找父元素
如题,其实本质的需求是找到A元素之后,根据A元素找到它对应的B元素,即,找到A,同时找到B;而不是根据A找B,即只找到B;这样讲很绕,很拗涩是不是?所以,很多兄弟想真正解决这个问题的时候google或百度进去,看了半天才发现文不对题,浪费了时间。
为了更进一步解释清楚,请看个栗子🌰:
拿我自己的csdn专栏 PHP篇 ,作为Mark党,看到这么多好棒的文章(这样夸自己是不是很无耻捏?😛,其实我自己都脸红了捏🤗)怎么办,怎么办,怎么办?当然是马上M起来啊,可是一个一个复制粘贴,很不像猿的style,怎么办?跑程序喽!!
Markdown的链接格式是酱紫滴:[标题](url);最简单的想法就是Python
+selenium
,然后获取页面元素,拼成这个格式。
- 先看文档结构图:
思路一: 获取<ul class="column_article_list">
下的所有li
里的a链接,然后获取<ul class="column_article_list">
下的所有li
里的h2标题,再把两个list对应拼接成结果;思路没有问题,但操作比较麻烦,而且这个类如果用到其他页面的时候,如果这个li里有多个超链接,这个方法就不好使了。
思路二: 获取<ul class="column_article_list">
下的所有li
里的h2标题,再通过h2获取父级的父级即a链接,通用,方便,简单,但问题就是如何获取?直接上代码:
1
2
3
4
5
6
7
8
|
locator = (By.XPATH, '//h2[@class="title"]' ) titles = self .timeout.until(EC.presence_of_all_elements_located(locator)) for t in titles: # 通过标题获取对应的文章的超链接 link = t.find_element(By.XPATH, './/..//..' ) # 组合成markdown格式超链 fmt = "[%s](%s)" % (t.text, link.get_attribute( 'href' )) print (fmt) |
解释一下,有学员问到为什么使用parent
不能获取父级元素?
在selenium
中,通过webdriver api
获取得元素,是webelement.@@xxWebElement
(其中的@@xx是根据浏览器驱动来的);而WebElement
的parent
,返回的是WebDriver
也就是回到了driver上去,因此,这样走,不是不行,而是绕远了,而且,也不会和当前的对像对应相关了,所反而不如上面的思路二直接一些。
下面是送福利时间,直接上完整csdn专辑页面转M代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
#!/usr/bin/env python # -*- coding:utf8 -*- from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC class CSDNMarkdown( object ): driver = None timeout = None album_url = "" waiter = None def __init__( self , album): ''' 初始化 ''' # 请求url self .album_url = album # 初始化webdriver self .driver = webdriver.Firefox() # 打开页面 self .driver.get( self .album_url) # 设置等待上限5秒 self .timeout = WebDriverWait( self .driver, 5 ) self .waiter = WebDriverWait( self .driver, 2 ) def turn( self ): # 获取第一页文章标题及超链接,并组合markdown链接 self .get_title() # 先打开第二页 p = self .driver.current_url # 翻页直到最后一页 while p is not None : p = self . next () # 获取每一页文章标题及超链接,并组合markdown链接 self .get_title() def next ( self ): try : # 判断是否到了末页 locator = (By.CSS_SELECTOR, '.js-page-next.js-page-action.ui-pager.ui-pager-disabled' ) self .waiter.until(EC.presence_of_element_located(locator)) return None except : # 判断是否有分页 try : # 找到下一页按钮 locator = (By.CSS_SELECTOR, '.js-page-next.js-page-action.ui-pager' ) nextPage = self .timeout.until(EC.presence_of_element_located(locator)) # 翻页 nextPage.click() return self .driver.current_url except : return None def get_title( self ): # 获取专栏的每一项的标题 titles = self .driver.find_elements(By.XPATH, '//h2[@class="title"]' ) for t in titles: # 通过标题获取对应的文章的超链接 link = t.find_element(By.XPATH, './/..//..' ) # 组合成markdown格式超链 fmt = "[%s](%s)" % (t.text, link.get_attribute( 'href' )) print (fmt) def __del__( self ): self .driver.close() if __name__ = = "__main__" : album_url = 'https://blog.csdn.net/yageeart/article/category/854202' app = CSDNMarkdown(album_url) app.turn() |
最后,如果你也想尝试自动化测试,或者多了解下自动化测试,一起来吧
转:https://www.cnblogs.com/phplee/articles/11634285.html