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

前言

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

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 xlwt

from 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=0

try:
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 webdriver

browser=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”)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值