如题,其实本质的需求是找到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链接,通用,方便,简单,但问题就是如何获取?直接上代码:
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代码:
#!/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()
最后,如果你也想尝试自动化测试,或者多了解下自动化测试,一起来吧:
浙公网安备 33010602011771号