美文网首页python
MechanicalSoup库

MechanicalSoup库

作者: 小温侯 | 来源:发表于2018-07-21 23:14 被阅读394次

介绍

MechanicalSoup的定位是功能性的网页抓取和交互库。它最大的特点是可以和网页交互,填充一些表单。它的底层使用的是BeautifulSoup(也就是bs4)和requests库,因此如果你熟悉后两个库,这个库上手会很容易。MechanicalSoup的主页是https://mechanicalsoup.readthedocs.io/,目前没有官方中文文档。

简单的例子

这里翻译一个官方文档上的教程:MechanicalSoup tutorial

第一次接触,一点点深入

作为一个简单的例子,我们将访问<http://httpbin.org/,它是一个设计用来测试类似MechanicalSoup的工具的网站。

首先,让我们新建一个浏览器(browser)对象:

>>> import mechanicalsoup
>>> browser = mechanicalsoup.StatefulBrowser()

要自定义新建browser的方式(比如说修改user-agent、选择HTML解析器、响应404 Not Found错误的方式等等),请查阅__init__()

现在,打开我们想要的网页:

>>> browser.open("http://httpbin.org/")
<Response [200]>

open()的返回值是一个类型为requests.Response的对象。事实上,MechanicalSoup使用了requests库实际对网站发送请求,因此收到这样的对象类型我们一点也不奇怪。简单来说,它包含了服务器返回的数据(data)和元数据(meta-data)。你可以看到HTTP返回码是200,这表示“OK”,这个对象同时也包含了所有我们刚刚下载的页面内容。

和一个正常的浏览器地址栏一样,browser会记住正在使用的URL:

>>> browser.get_url()
'http://httpbin.org/'

现在,让我们将链接指向/form/post

>>> browser.follow_link("forms")
<Response [200]>
>>> browser.get_url()
'http://httpbin.org/forms/post'

我们向follow_link()中传入了一个正则表达式"forms",它会找到一个文本符合这个正则式的链接。调用follow_link()有很多其他方法,但我们以后再谈。

现在我们正在访问http://httpbin.org/forms/post, 这个页面包含一个表单。让我们看一下页面内容:

>>> browser.get_current_page()
<!DOCTYPE html>
<html>
...
<form action="/post" method="post">
...

事实上,get_current_page()返回的类型是bs4.BeautifulSoup。BeautifulSoup,也就是bs4,是Mechanicalsoup使用的第二个库:它是一个HTML操作库。现在你可以使用BeautifulSoup来在页面的标签之间跳转。比如说,获得所有的<legend>标签:

>>> browser.get_current_page().find_all('legend')
[<legend> Pizza Size </legend>, <legend> Pizza Toppings </legend>]

要填充一个表单,我们要告诉MechanicalSoup我们需要填写和提交的表单位置:

>>> browser.select_form('form[action="/post"]')

select_form()的参数是一个CSS选择器。这里我们选择了所有名为form且带一个属性名为action值为"/post“的HTML标签。由于这个页面里只有一张表单,使用browser.select_form()也可以取巧的得到这个表单。

现在,给表单的字段赋值。首先,有哪些可用的字段呢?你可以使用print_summary()来打印当前被选择的表单的摘要:

>>> browser.get_current_form().print_summary()
<input name="custname"/>
<input name="custtel" type="tel"/>
<input name="custemail" type="email"/>
<input name="size" type="radio" value="small"/>
<input name="size" type="radio" value="medium"/>
<input name="size" type="radio" value="large"/>
<input name="topping" type="checkbox" value="bacon"/>
<input name="topping" type="checkbox" value="cheese"/>
<input name="topping" type="checkbox" value="onion"/>
<input name="topping" type="checkbox" value="mushroom"/>
<input max="21:00" min="11:00" name="delivery" step="900" type="time"/>
<textarea name="comments"></textarea>

处理文本字段很简单:只需要根据input元素的name属性,给它们赋值就行了。

>>> browser["custname"] = "Me"
>>> browser["custtel"] = "00 00 0001"
>>> browser["custemail"] = "nobody@example.com"
>>> browser["comments"] = "This pizza looks really good :-)"

对于单选按钮,也很简单:单选按钮有一些包含相同name不同值的input标签,你只需要选择你想要那个就行了(我们这里要选择的是name属性为"size"value属性是"medium"的元素):

>>> browser["size"] = "medium"

对于选择按钮,使用的是和单选按钮一样的机制:

>>> browser["topping"] = "bacon"

但我们也可以通过赋值一个列表给字段来选择多个选择框:

>>> browser["topping"] = ("bacon", "cheese")

事实上,browser["..."] = "..."(比如调用__setitem__())只是一个填充表单的助手,你可以使用任何BeautifulSoup提供的工具来修改soup对象,MechanicalSoup会负责为你进行表单提交。

让我们看看填充好的表单时什么样的:

>>> browser.launch_browser()

lauch_browser()会启动一个真实的web浏览器来访问我们browser对象的页面,包括我们刚刚对表单所做的改变(注意它不会打开一个真正的web页面,但是会创建一个包含页面内容的临时文件并将browser指向这个页面)。尝试选择其他的方框和文本字段的内容并重新载入browser。

结合浏览器的web开发工具,这个方法会变得非常有用。举个例子,在Firefox里,右键选择”检查元素“,你可以获取到修改一个字段所需要的全部信息(具体来说就是namevalue属性)。

使用print_summary()来检查新的内容也是可以的(我们已经在列出字段时使用过了):

>>> browser.get_current_form().print_summary()
<input name="custname" value="Me"/>
<input name="custtel" type="tel" value="00 00 0001"/>
<input name="custemail" type="email" value="nobody@example.com"/>
<input name="size" type="radio" value="small"/>
<input checked="" name="size" type="radio" value="medium"/>
<input name="size" type="radio" value="large"/>
<input checked="" name="topping" type="checkbox" value="bacon"/>
<input checked="" name="topping" type="checkbox" value="cheese"/>
<input name="topping" type="checkbox" value="onion"/>
<input name="topping" type="checkbox" value="mushroom"/>
<input max="21:00" min="11:00" name="delivery" step="900" type="time"/>
<textarea name="comments">This pizza looks really good :-)</textarea>

假设我们已经对当前的表单内容满意了,我们可以提交它(比如说,模拟点击提交按钮):

>>> response = browser.submit_selected()

它返回的不再是一个HTML页面,因此browser不会把它解析成一个BeautifulSoup对象,但是我们仍然可以看到它包含的内容:

>>> print(response.text)
{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "comments": "This pizza looks really good :-)",
    "custemail": "nobody@example.com",
    "custname": "Me",
    "custtel": "00 00 0001",
    "delivery": "",
    "size": "medium",
    "topping": [
      "bacon",
      "cheese"
    ]
  },
...

这里是完整的例子(examples/expl_httpbin.py):

import mechanicalsoup

browser = mechanicalsoup.StatefulBrowser()
browser.open("http://httpbin.org/")

print(browser.get_url())
browser.follow_link("forms")
print(browser.get_url())
print(browser.get_current_page())

browser.select_form('form[action="/post"]')
browser["custname"] = "Me"
browser["custtel"] = "00 00 0001"
browser["custemail"] = "nobody@example.com"
browser["size"] = "medium"
browser["topping"] = "onion"
browser["topping"] = ("bacon", "cheese")
browser["comments"] = "This pizza looks really good :-)"

# Uncomment to launch a real web browser on the current page.
# browser.launch_browser()

# Uncomment to display a summary of the filled-in form
# browser.get_current_form().print_summary()

response = browser.submit_selected()
print(response.text)

相关文章

  • MechanicalSoup库

    介绍 MechanicalSoup的定位是功能性的网页抓取和交互库。它最大的特点是可以和网页交互,填充一些表单。它...

  • 推荐一款小众且好用的 Python 爬虫库 - Mechanic

    1. 前言 今天推荐一款小众轻量级的爬虫库:MechanicalSoup MechanicalSoup,也是一款爬...

  • 再推荐一款小众且好用的 Python 爬虫库 - Mechani

    1. 前言 大家好,我是安果! 今天再推荐一款小众轻量级的爬虫库:MechanicalSoup Mechanica...

  • 公司数据库逻辑

    pro库 drds库 通道库 查询库 pg库 bi库 tidb库 odps查询 pro库和drds库是线上数据库 ...

  • Lua库函数概览

    Lua库函数概览数学库 table库 字符串库 IO库 os库 调试库

  • Swift 静态库调研

    一、关于库的背景知识1、静态库和动态库静态库动态库系统动态库Cocoa Touch Framework静态库 v....

  • iOS 创建静态库(.a)

    静态库(.a) 文章类型: 学习笔记 1. 静态库简介 库的概念: 什么是库? 库的分类: 库的存在形式: 静态库...

  • 目录一、库二、静态库、动态库、Framework三、打包静态库 1、.a静态库和.framework静态库的区别 ...

  • iOS 静态库和动态库的制作

    静态库和动态库 一、静态库和动态库的存在形式 静态库: .a 和 .framework 动态库: .dylib 和...

  • 动态库与静态库相互连接

    动态库--动态库 场景:App --> 动态库A --> 动态库 B 存在问题:动态库B应该的路径 = 动态库A的...

网友评论

    本文标题:MechanicalSoup库

    本文链接:https://www.haomeiwen.com/subject/jibkmftx.html