python selenium根据子元素查找父元素

如题,其实本质的需求是找到A元素之后,根据A元素找到它对应的B元素,即,找到A,同时找到B;而不是根据A找B,即只找到B;这样讲很绕,很拗涩是不是?所以,很多兄弟想真正解决这个问题的时候google或百度进去,看了半天才发现文不对题,浪费了时间。

为了更进一步解释清楚,请看个栗子🌰:

拿我自己的csdn专栏 PHP篇 ,作为Mark党,看到这么多好棒的文章(这样夸自己是不是很无耻捏?😛,其实我自己都脸红了捏🤗)怎么办,怎么办,怎么办?当然是马上M起来啊,可是一个一个复制粘贴,很不像猿的style,怎么办?跑程序喽!!

Markdown的链接格式是酱紫滴:[标题](url);最简单的想法就是Pythonselenium,然后获取页面元素,拼成这个格式。

  • 先看文档结构图:

要获取的内容

思路一: 获取<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 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是根据浏览器驱动来的);而WebElementparent,返回的是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()
 
        # 先打开第二页
        = self.driver.current_url
        # 翻页直到最后一页
        while is not None:
            = 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 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

posted @ 2021-11-17 18:56  rmticocean  阅读(658)  评论(0编辑  收藏  举报