背景
今天用selenium爬“证券日报”的搜索页,前面的“获取源代码”、“数据提取”、“数据清洗”都挺顺利,就是到了这个翻页掉坑里去了。
问题与尝试解决
问题1
页面没有“下一页”!这提高了一些难度。
尝试解决1
使用edge的审查页面元素,发现翻页按钮都在<div class="pagination pagination-centered"><ul>
下,并且每个按钮的链接都被<li>……</li>
包围。
于是我尝试用正则表达式,将按钮的链接提取出来。
代码如下:
btn_re = re.compile('<li>.*?<a href="(.*?)">.*?<\/a>, re.S)
btn是一个列表,我使用page变量来标识每一页。
for page in range(2, 11):
btn = re.findall(btn_re, source) # source是网页源代码
wd.get(btn[page]) # wd = webdrive.Edge()
问题2
虽然我的链接提取正确,但它就是无法访问,返回的页面是空白。
尝试解决2
于是我决定用selenium的模拟点击来翻页。
我使用的css选择器来获取。
btn= 'body > div > div.pagination.pagination-centered > ul > li:nth-child(' + str(page) + ') > a'
wd.find_element_by_css_selector(btn_re)
于是成功翻页。
问题3
但又出现了新的问题。翻页的过程中,每个按钮对应的页码会发生变化,这就导致我爬取过程中会漏掉一些页面。
尝试解决3
但是我发现虽然按钮对应的页码会变,但是每个页码对应的文本不变。即页码和文本一直保持一对一的关系。
最终我采用了xpath的文本定位方法。
例如定位14按钮
# 浏览器直接复制xpath路径,得到
/html/body/div/div[2]/ul/li[10]/a
# 但我的目的是在<ul>中搜索<a对应的text,于是去掉<li[10]>中的索引,得到
/html/body/div/div[2]/ul/li/a
# 使用[text()="文本"]搜索,得到
/html/body/div/div[2]/ul/li/a[text()="文本"]
# 使用page变量来代表页码,得到可变的xpath路径
btn = r'/html/body/div/div[2]/ul/li/a[text()="' + str(page) + r'"]'
# 点击
wd.find_element_by_xpath(btn).click()
总结
在目标与文本一一对应的时候,可以使用xpath根据文本定位目标。
语法
根据网上查到的资料,共有两种写法
# 精准定位,目标文本和我们搜索的文本完全相同
browser.find_element_by_xpath("//*[text()='文本']")
# 相对定位,目标文本包含我们搜索的文本
rowser.find_element_by_xpath("//*[contains(text(),'文本')]")