频道栏目
首页 > 资讯 > 其他综合 > 正文

用Beautiful Soup进行屏幕抓取

17-09-01        来源:[db:作者]  
收藏   我要投稿

数据抓取操作步骤

创建用于发送HTTP请求时将用到的所有值 发出HTTP请求并下载所有数据 解析这些数据文件中需要的数据,

具体操作步骤

首先需要弄清需要访问哪个URL以及需要哪种HTTP方法。HTTP方法类似于:

method="post"

URL类似于:

action="Data_Elements.aspx?Data=2"

Beautiful Soup

Beautiful Soup是一个Python库,用于从HTML和XML文件中提取数据。它使用您喜欢的解析器来提供导航、搜索和修改解析树的惯用方法。它通常节省程序员几个小时或几天.

这是不同的beautiful soup解析器的比较

这里写图片描述

用Beautiful Soup提取隐藏字段

任务:使用 BeautifulSoup 处理 HTML,提取出
“__EVENTVALIDATION”和“__VIEWSTATE”的隐藏表格字段值,并在数据字典中设置相应的值。

代码实现:

def extract_data(page):
# 同之前的方法一样,定义字典,方便对键赋值
    data = {"eventvalidation": "",
            "viewstate": ""}
    with open(page, "r") as html:
# 这里用lxml解析器,后文会做简要介绍
        soup = BeautifulSoup(html, "lxml")
        ev = soup.find(id="__EVENTVALIDATION")
# 把ev中value的值取出来给data的键
        data["eventvalidation"] = ev["value"]

        vs = soup.find(id="__VIEWSTATE")
        data["viewstate"] = vs["value"]

    return data

解析器图片

推荐使用lxml作为解析器,因为效率更高. 在Python2.7.3之前的版本和Python3中3.2.2之前的版本,必须安装lxml或html5lib, 因为那些Python版本的标准库中内置的HTML解析方法不够稳定.

提示: 如果一段HTML或XML文档格式不正确的话,那么在不同的解析器中返回的结果可能是不一样的

find()方法

find( name , attrs , recursive , text , **kwargs )

find_all() 方法将返回文档中符合条件的所有tag,尽管有时候我们只想得到一个结果.比如文档中只有一个标签,那么使用 find_all() 方法来查找标签就不太合适, 使用 find_all 方法并设置 limit=1 参数不如直接使用 find() 方法.下面两行代码是等价的:

soup.find_all('title', limit=1)
# [
] soup.find('title') #

唯一的区别是 find_all() 方法的返回结果是值包含一个元素的列表,而 find() 方法直接返回结果.

find_all() 方法没有找到目标是返回空列表, find() 方法找不到目标时,返回 None .

print(soup.find("nosuchtag"))
# None

soup.head.title 是 tag的名字 方法的简写.这个简写的原理就是多次调用当前tag的 find() 方法:

soup.head.title
# 
soup.find("head").find("title") #

练习:获取运营商列表

任务

获取一个包含所有航空公司的列表。在你所返回的数据中要去掉所有类似 “All U.S. Carriers” 的组合。最终你应该返回一个含有运营商编码的列表。

部分被处理代码:

        
            
                

            

            
                

解决方法:

def extract_carriers(page):
    data = []

    with open(page, "r") as html:
        soup = BeautifulSoup(html, 'lxml')
# find方法里为什么必须要用id定位:问题一
        carrier_list=soup.find(id='CarrierList')
        options=carrier_list.find_all('option')
        for tag in options:
# 取出标签value所对应的值,添加到列表中。不要标签值中带有All的
            if 'All' not in tag['value']:
                data.append(tag['value'])
    return data

问题一回答

注意find()方法格式:find( name, attrs, recursive, text, **kwargs)。
虽然name标签也是具有唯一性的,但由于 find 函数已经使用 name 参数名称来接受 tag 类型的信息,下面两个语句其实是等价的:

carrier_tag = soup.find(name='CarrierList')
carrier_tag = soup.find('CarrierList')

相当于搜索这类标签: ,那么在当前情况下必然是搜索不到的~

如果想使用 name 属性来搜索,可以使用以下语法:

carrier_list = soup.find('select', {'name': 'CarrierList'})

练习:处理所有数据

练习:专利数据库

处理XML局部文件时通常会遇到这样的错误:Error parsing XML: junk after document element。这是因为一般合法的XML文件只有一个主根节点,比如:


    
    
    

如果出现了Error parsing XML: junk after document element这样的错误,你的想法可能只要主根有多个节点


    


    
    

事实上通常情况下,这种文件通常是由多个相连的 XML 文档构成的。一种解决方法是将文件拆分为多个文档,并将这些文档处理为有效的 XML 文档。

任务:按照

def split_file(filename):
    with open(filename) as infile:
        n = -1 # 由于第一次遇到 '
        
   
相关TAG标签
上一篇:Python基础整理操作积累
下一篇:java.lang.IllegalStateException: ApplicationEventMulticaster not initialized
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站