小小白谈:python之网页数据爬取

  • 前言
  • python爬数据需要的两个知识
  • find_element会遇到的问题
  • 强大的python
  • 获取表格主体
  • 通过标签获取所有行对象
  • 遍历所有列对象
  • 获取每一行中所有元素
  • go to next page
  • 这个程序是画xmind的


前言

因为工作需要,需要对某些特定网页的表格内容固定,有事遇到一张表格有上千张网页,简单的“复制+粘贴”会让一个正常人崩溃的,也正是因为我这样崩溃过,所以痛下决心:一定要学会用脚本(当然有同学提议:按键精灵,实际效果不理想)。

python爬数据需要的两个知识

一、html标签语言的理解
二、 selenium的模块(当然还有其他模块也具备这个功能,但目前我只会这个模块)
html本质是标记,它解决的核心问题就是从服务器把数据送到客户端的浏览器,如何让这个数据很好的被理解(解析),它把所有的数据当成元素来对待,然后对元素进行层级划分。这是我理解的HTML语言的灵魂,如有不对,望批评指正。
html语言中几乎所有的标记都是成对使用,如:“《html》…《/html》(说明一下:这边的“《》”其实是“<>”因为在网页中使用了标准格式的话,浏览器会解析,就不会显示)”,这表示用两个html标签把这两个标签之间的所有内容标记为一个元素,打开所有的网页几乎都是以《html》开头,以《/html》结尾的,也可以说一个网页就是一个元素,这个元素的标签就是HTML。同时,HTML元素也被称为根元素,在根元素里可以再定义其他元素,比如:head和body,如下
《Html》
《head》…《/head》
《body》…《body》
《/html》
head和body之间的关系是同级,相当于兄弟姐妹,HTML就是他的老爹。当然head和body可以再有自己的儿子、女儿,儿子、女儿可以再有后代。一个网页就这样丰富起来了。理解了这点,网页元素定位就好理解多了。
selenmiu模块中提供很多元素定位的函数,我就挑一个来说说吧:find_element_by_xpath,使用路径来查找元素,这个路径其实就是元素的层级。可以选绝对路径和相对路径。实际使用中,使用相对路径较多,而且跟灵活。后面要提到对一个标签树进行遍历,如果不使用相对路径,可能没法做。
“./”和“…/”,“.”表示当前路径,“…”表示当前路径的父节点路径。假如:我现在的路径为:body,“./”的绝对路径为:“html/body/”,“…/”为“html/”。

find_element会遇到的问题

在定位元素时,我遇到了不少的坑。感谢各位前辈的指点,才有幸爬出坑。这里我也总结下,如果有人像我一样也是从小小白开始,也可少跌坑里。
1、网页handle问题,这个问题往往出现在本来元素定位好好的,提交了一个请求或者跳转了链接后,定位不了了。这是因为网页跳转后,你在元素定位的时候还在原来的网页定位。这个时候 sreach_window = browser.current_window_handle就可以了
2、frame问题,有些网页,一个页面上有几个网页的内用,定位的时候先要定位到需要的frame中
3、showd dom问题,如果你看到《showd-root》的标签,表示这个标签内的元素是被隐藏的,正常使用find-element_by是找不到元素的,有大神给出了解决方式,但我还没弄懂,当时我是需要点击某个元素,但是不让定位,然后用了一个非常简单粗暴的办法搞定的。

强大的python

python的优点:python有丰富的模块,几乎所有我能想到的,它都有模块支持。什么画图、写表什么都是家常便饭。所有用python写的代码往往很短,只需几行就能达到你要的功能。但凡事有利有弊,python的问题:因为模块什么的都是别人写好的,我们不涉及底层如何实现,对执行效率要求很高的话,python可能就不是很好的选择。我写了一个递归程序,遍历标签树并把结构画到xmind上。树的元素有7000多个,代码13行,16G内存20核的电脑跑了7个小时才画好。说实话没比人工快。

最后附上两个代码

这个是抓取网页表格的,表格有100页
 #coding: UTF-8
 import time
 import xlwtfrom selenium import webdriver
browser=webdriver.Chrome()
 url=“XXXXXXXXXXXXXX”
 browser.get(url)
 browser.implicitly_wait(5)#browser.switch_to.frame(“mainframe”) # 切换到frame框架中
#创建一张表格保存数据
 download=xlwt.Workbook()
 sheet1=download.add_sheet(“sheet1”,cell_overwrite_ok=True)
 row_num=0 #写表格的行地址
 col_num=0 #写表格的列地址#获取表头
 table=browser.find_element_by_class_name(“odd_bg”)
 trlist=table.find_elements_by_tag_name(“th”)
 for col in trlist:
 sheet1.write(row_num,col_num,col.text)
 col_num=col_num+1
 row_num=row_num+1
 col_num=0try:


for i in range(1,100):

获取表格主体

table = browser.find_element_by_class_name(“ltable”)

通过标签获取所有行对象

trlist = table.find_elements_by_tag_name(“tr”)

遍历所有列对象

for row in trlist:

获取每一行中所有元素

tdlist = row.find_elements_by_tag_name(“td”)
for col in tdlist:
sheet1.write(row_num, col_num, col.text)
col_num = col_num + 1
row_num = row_num + 1
col_num = 0

go to next page

print(“page”, i, “done!”)
 browser.implicitly_wait(5)
 #点击下一页
 browser.find_element_by_link_text(">").click()
 sreach_window = browser.current_window_handle # 此行代码用来定位当前页面finally:
 download.save(“XXXX.xls”)

这个程序是画xmind的

import xmind
 from selenium import webdriverbrowser=webdriver.Chrome()
 browser.get(“XXXXXXXXXXl”)
 browser.implicitly_wait(5)#这是递归函数,ergodic_tree
 def ergodic_tree(node_handle,ul_id_name):
 tree_leve=browser.find_element_by_id(ul_id_name)
 leve_parents=tree_leve.find_elements_by_xpath("./li/a")
 for leve_parent in leve_parents:
 print(leve_parent.text)
 next_handle=node_handle.addSubTopic()
 next_handle.setTitle(leve_parent.text)
 #用xpath的方式找该元素的子元素,如果没有子元素,次节点结束,进入下一循环,即检查该元素的兄弟元素。如果有则递归下一层
 try:
 # 这里的ul元素和a元素是同级的,“./ul”相当于“./a/ul","…/“表示当前节点的父节点
 leve_ul_parent = leve_parent.find_element_by_xpath(”…/ul")
 next_ul_id_name = leve_ul_parent.get_attribute(“id”)
 print(next_ul_id_name)
 except:
 continue
 else:
 ergodic_tree(next_handle,next_ul_id_name)#创建xmind中心节点
 work_book=xmind.load(“a.xmind”)
 s1=work_book.getPrimarySheet()
 s1.setTitle(“xxx”)
 r1=s1.getRootTopic()
 r1.setTitle(“XXXXX]”)id_name=“tree_2_ul”
 try:
 ergodic_tree(r1, id_name)
 finally:
 xmind.save(work_book,path=“a.xmind”)