selenium.webdriver 能绕过采取前端javascript加密的网站,也不必去考虑什么 iframe的框架关系,直接去读取最终显示的页面,虽然有他的笨重缺点,但是一招破百防,无招胜万招。
最近因为要爬一个前端javascript加密的网站数据,简单调试了一个爬虫python程序,把几点小经验记录一下。
1、python的爬虫调试过程,当然必选 Jupyter Notebook 了,chrome打开页面后,F12大法,随意查 xpath,随意遍历dom对象,不用重启程序,想修改什么查询,就修改什么查询。
2、我的chrome使用了绿色版(78.0.3904),最关键的原因是这个版本是能支持flash的最终版了,包括webdriver也都不在搜索路径中,所以要自定义程序路径:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
opt = Options()
opt.binary_location = "D:/chrome_x86/App/chrome.exe"
browser = webdriver.Chrome (executable_path="D:/chrome_x86/chromedriver.exe", options=opt)
browser.get("......")
3、页面的dom对象查询,虽然webdriver也提供了 find_element……功能,但是比起BeautifulSoup还是弱了些,所以还是:
html_text = browser.page_source
soup = BeautifulSoup(html_text, 'html.parser')
4、所寻找的dom对象,虽然F12可以找到,但是soup不能直接找到,然后发现是藏在<section>中了,先找到section,再在section中继续查找就能找到
sectionS = soup.find_all("section")
section = sectionS[0]
labels = section.find_all("label")
5、网页跳转过程中,会有数据加载的过程,传统的办法是用time.sleep(…)等待一会。其实还可以用try…except…加上无限循环来解决,而且效果感觉更好。
6、上一点所说的,还包括click网页上的dom对象(比如button),有时会出现click错了dom对象,然后程序崩溃的问题,估计是chrome和webdriver不匹配,这时try…except…加无限循环,可以确保不管是加载没有完成,还是程序偶而不兼容,都能click上想要的button。下面的例子,是稳保能点上“返回”按钮的办法。
while True:
try:
btnS = browser.find_elements_by_xpath("//button")
for bt in btnS:
if "返回" in bt.text:
bt.click()
break
break
except:
pass
7、怎么样读表格数据?因为碰到了虽然表格基本相同,但是表头还是有时有些差别的情况,这时候就不能直接数表格的格子数来取数据,而是要先读取表头,根据表头行,来取下面数据行的数据。
tr_line = subtable.find("……")
name_cols = {}
# 先读表头
td_S = tr_line.find_all("th")
for i, td in enumerate(td_S):
name_cols[td.text] = i
# 再读数据行
tr_line_S = subtable.find_all(class_ = "……")
if len(tr_line_S) > 1:
print ("--",len(tr_line_S),"--",end="")
for tr_line in tr_line_S:
td_S = tr_line.find_all("td")
# 根据表头,取具体的数据
lbm = td_S[name_cols["……"]].text
sliang = td_S[name_cols["……"]].text
slv = td_S[name_cols["……"]].text
8、因为取得数据太多,程序有时会跑死,还得手工恢复现场。这是先看一下,记住Chrome跑死在哪个页面,重启程序里,在browser.get("…")之后,来个pause=input("PAUSE"),把程序暂停一下,再手工点击Chrome的内容,回到断掉的那一页,就可以继续爬下去了。数据也要时不时断点存储,以保证在断点处能进行恢复,存储数据,joblib.dump是我的最爱了。