web 3d机械手臂_通过机械化和精美汤轻松进行Web数据收集

web 3d机械手臂

使用基本的Python模块可以编写与网站交互的脚本,但是如果不需要的话,则不需要这样做。 Python 2.x中的urlliburllib2模块,以及Python 3.0中的统一urllib.*子软件包,在URL末尾获取资源方面做得很好。 但是,当您想要与在Web页面上找到的内容进行某种程度的复杂交互时,您确实需要机械化库( 有关下载链接,请参见参考资料 )。

自动化Web抓取或其他模拟用户与Web站点交互的主要困难之一是服务器使用cookie来跟踪会话进度。 显然,cookie是HTTP标头的一部分,并且在urllib打开资源时固有地可见。 此外,标准模块Cookiehttp.cookie在Python 3)和cookielibhttp.cookiejar在Python 3)以比原始文本的处理的更高级别处理这些头的帮助。 即使这样,在此级别上执行此处理也比必要的麻烦。 机械化库将这种处理方式带入了更高的抽象水平,并使您的脚本(或交互式Python Shell)的行为与实际的Web浏览器非常相似。

Python的机械化灵感来自Perl的WWW:Mechanize ,它具有类似的功能范围。 当然,作为一个长期使用Python的人,我发现机械化功能更加强大,它似乎遵循了这两种语言的通用模式。

机械化的密友是同样出色的库Beautiful Soup (请参阅参考资料中的下载链接)。 对于在实际Web页面中经常发现的近似有效HTML,这是一个奇妙的“草率解析器”。 您无需将Beautiful Soup与mechanize一起使用,反之亦然,但是在与“实际存在的Web”进行交互时,您经常会希望同时使用这两个工具。

一个真实的例子

我在多个编程项目中使用过机械化。 最近的一个项目是从流行的网站收集与某些条件匹配的名称列表。 该站点具有一些搜索功能,但没有用于执行此类搜索的任何官方API。 尽管读者也许可以更具体地猜测我在做什么,但我将更改所提供代码的细节,以避免在被抓取的网站或客户上提供过多的信息。 在一般形式下,非常类似于我介绍的代码将在类似的任务中通用。

开始的工具

在实际开发Web抓取/分析代码的过程中,我发现能够以交互方式查看,戳戳和制作Web页面的内容,以弄清相关Web页面上实际发生的事情,这是非常宝贵的。 通常,这些是站点内的页面集,这些页面集可以通过查询动态生成(但具有一致的模式),也可以按照相当严格的模板预先生成。

这样的互动实验的一个有价值的方法是使用机械化本身Python的外壳内,特别是在像IPython的增强Shell(请参阅相关信息中的链接)。 通过这种方式进行探索,您可以在编写最终脚本以执行您要在生产中进行的交互之前,请求各种链接的资源,提交表单,维护或操作站点cookie等。

但是,我发现在实际的现代Web浏览器中,与网站的许多实验性交互都可以更好地完成。 看到一个方便呈现的页面,可以更快地了解给定页面或表单所发生的情况。 问题在于,仅渲染页面只能提供一半的故事,也许还不到一半。 使用“页面源”可以使您更进一步。 为了真正了解给定网页或与Web服务器的交互序列背后的内容,我发现还需要更多。

为了获得这些勇气,我通常使用Firebug(请参阅参考资料中的链接)或Firefox的Web开发器插件(或最新Safari版本中的内置可选Develop菜单,但这是针对不同的读者)。 所有这些工具使您可以执行诸如显示表单字段,显示密码,检查页面DOM,查看或运行Javascript,监视Ajax流量等操作。 比较这些工具的好处和怪癖是另一篇文章,但是如果您进行任何面向Web的编程,请务必熟悉它们。

无论您使用什么特定工具来尝试与之进行自动交互的网站进行试验,与编写执行任务所需的紧凑的机械化代码相比,您可能要花费更多的时间弄清楚该站点的实际运行情况。

搜索结果刮板

出于上面提到的项目的目的,我将一百行脚本分为两个函数:

  • 检索我感兴趣的所有结果
  • 从检索到的页面中提取我感兴趣的信息

为了方便开发,我以此方式组织了脚本。 当我开始任务时,我知道我需要弄清楚如何做这两件事。 我感觉到我想要的信息是在一般页面上的,但是我还没有检查这些页面的具体布局。

通过首先检索一批页面并将它们仅保存到磁盘,我可以回到从那些保存的文件中提取我关心的信息的任务。 当然,如果您的任务涉及使用检索到的信息来在同一会话中制定新的交互,则需要使用略有不同的开发步骤序列。

因此,首先让我们看一下我的fetch()函数:

清单1.获取页面内容
import sys, time, os
from mechanize import Browser

LOGIN_URL = 'http://www.example.com/login'
USERNAME = 'DavidMertz'
PASSWORD = 'TheSpanishInquisition'
SEARCH_URL = 'http://www.example.com/search?'
FIXED_QUERY = 'food=spam&' 'utensil=spork&' 'date=the_future&'
VARIABLE_QUERY = ['actor=%s' % actor for actor in
        ('Graham Chapman',
         'John Cleese',
         'Terry Gilliam',
         'Eric Idle',
         'Terry Jones',
         'Michael Palin')]

def fetch():
    result_no = 0                 # Number the output files
    br = Browser()                # Create a browser
    br.open(LOGIN_URL)            # Open the login page
    br.select_form(name="login")  # Find the login form
    br['username'] = USERNAME     # Set the form values
    br['password'] = PASSWORD
    resp = br.submit()            # Submit the form

    # Automatic redirect sometimes fails, follow manually when needed
    if 'Redirecting' in br.title():
        resp = br.follow_link(text_regex='click here')

    # Loop through the searches, keeping fixed query parameters
    for actor in in VARIABLE_QUERY:
        # I like to watch what's happening in the console
        print >> sys.stderr, '***', actor
        # Lets do the actual query now
        br.open(SEARCH_URL + FIXED_QUERY + actor)
        # The query actually gives us links to the content pages we like,
        # but there are some other links on the page that we ignore
        nice_links = [l for l in br.links()
                        if 'good_path' in l.url
                        and 'credential' in l.url]
        if not nice_links:        # Maybe the relevant results are empty
            break
        for link in nice_links:
            try:
                response = br.follow_link(link)
                # More console reporting on title of followed link page
                print >> sys.stderr, br.title()
                # Increment output filenames, open and write the file
                result_no += 1
                out = open(result_%04d' % result_no, 'w')
                print >> out, response.read()
                out.close()
            # Nothing ever goes perfectly, ignore if we do not get page
            except mechanize._response.httperror_seek_wrapper:
                print >> sys.stderr, "Response error (probably 404)"
            # Let's not hammer the site too much between fetches
            time.sleep(1)

在对感兴趣的站点进行了交互式探索之后,我发现希望执行的查询具有一些固定元素和一些可变元素。 我只是将它们连接成一个大的GET请求,然后查看“结果”页面。 反过来,该结果列表包含指向我实际需要的资源的链接。 因此,我遵循这些规则(添加了一些try / except块,以防某些方式无法正常工作)并保存在这些内容页面上找到的所有内容。

很简单吧? 机械化可以做的还不止这些,但是这个简短的示例向您展示了它的功能。

处理结果

至此,我们完成了机械化。 剩下的就是弄清楚我们在fetch()循环中保存的fetch() HTML文件。 进程的批处理性质使我可以清晰地将它们分开,但是显然在另一个程序中, fetch()process()可能会更紧密地交互。 Beautiful Soup使得后处理比最初的获取更加容易。

对于此批处理任务,我们希望从在所获取的各种Web页面上找到的点点滴滴中生成表格逗号分隔值(CSV)数据。

清单2.以奇妙的方式使数据有条不紊,以Beautiful Soup结尾
from glob import glob
from BeautifulSoup import BeautifulSoup

def process():
    print "!MOVIE,DIRECTOR,KEY_GRIP,THE_MOOSE"
    for fname in glob('result_*'):
        # Put that sloppy HTML into the soup
        soup = BeautifulSoup(open(fname))

        # Try to find the fields we want, but default to unknown values
        try:
            movie = soup.findAll('span', {'class':'movie_title'})[1].contents[0]
        except IndexError:
            fname = "UNKNOWN"

        try:
            director = soup.findAll('div', {'class':'director'})[1].contents[0]
        except IndexError:
            lname = "UNKNOWN"

        try:
            # Maybe multiple grips listed, key one should be in there
            grips = soup.findAll('p', {'id':'grip'})[0]
            grips = " ".join(grips.split())   # Normalize extra spaces
        except IndexError:
            title = "UNKNOWN"

        try:
            # Hide some stuff in the HTML <meta> tags
            moose = soup.findAll('meta', {'name':'shibboleth'})[0]['content']
        except IndexError:
            moose = "UNKNOWN"

        print '"%s","%s","%s","%s"' % (movie, director, grips, moose)

process()的代码是对“美丽汤”的印象深刻的第一印象。 读者应阅读其文档,以获取有关模块详细信息的更多信息,但在此代码段中可以很好地体现总体感觉。 大多数汤代码由对页面的一些.findAll()调用组成,该页面可能仅是格式正确HTML。 这里抛出一些类似于DOM的.parentnextSiblingpreviousSibling属性。 这些类似于Web浏览器的“怪癖”模式。 我们发现汤是不是很解析树; 它更像一袋装满蔬菜的麻袋,可能会混入汤中(过滤一个比喻)。

结论

像我这样的老混蛋,甚至是一些年轻的读者,都会记得使用TCL Expect(或用Python和许多其他语言编写的作品)编写脚本的极大乐趣。 与外壳程序(包括远程程序,例如telnet,f​​tp,ssh等)的自动化交互相对简单,因为所有内容都在会话中显示 。 Web交互稍微有些微妙,因为信息在标头和正文之间划分,并且各种相关资源通常与href链接,框架,Ajax等捆绑在一起。 但是,原则上,您可以只使用wget类的工具来检索Web服务器可能提供的每个字节,然后运行与其他连接协议完全相同的Expect脚本样式。

在实践中,很少有程序员像我建议的wget + Expect方法那样致力于老式方法。 机械化仍然具有与那些不错的Expect脚本相同的熟悉和舒适感,并且即使不容易编写也一样容易编写。 Browser()对象命令(例如.select_form() .submit().follow_link()实际上只是最简单,最明显的说法,即“寻找并发送”,同时捆绑了所有复杂的功能。 Web自动化框架中需要的状态和会话处理。


翻译自: https://www.ibm.com/developerworks/opensource/library/l-python-mechanize-beautiful-soup/index.html

web 3d机械手臂

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值