如何用 Python 实现 Web 抓取?

【编者按】本文作者为 Blog Bowl 联合创始人 Shaumik Daityari,主要介绍 Web 抓取技术的基本实现原理和方法。文章系国内 ITOM 管理平台 OneAPM 编译呈现,以下为正文。

如何用 Python 实现 Web 抓取?

随着电子商务的蓬勃发展,笔者近年越来越着迷于比价应用。我在网络上(甚至线下)的每次购买,都是在各大电商网站深入调研后的结果。

笔者常用的比价应用包括:RedLaser, ShopSavvy 以及 BuyHatke。这些应用有效提高了价格透明度,进而为消费者节省了可观的时间。

但是,你是否想过,这些应用如何得到那些重要数据?通常,它们会借助 Web 抓取技术来完成该任务。

Web 抓取的定义

Web 抓取是抽取网络数据的过程。只要借助合适的工具,任何你能看到的数据都可以进行抽取。在本文中,我们将重点介绍自动化抽取过程的程序,帮助你在较短时间内收集大量数据。除了笔者前文提到的用例,抓取技术的用途还包括:SEO 追踪、工作追踪、新闻分析以及笔者的最爱——社交媒体的情感分析!

一点提醒

在开启 Web 抓取的探险之前,请确保自己了解相关的法律问题。许多网站在其服务条款中明确禁止对其内容进行抓取。例如,Medium 网站就写道:“遵照网站 robots.txt 文件中的规定进行的爬取操作(Crawling)是可接受的,但是我们禁止抓取(Scraping)操作。”对不允许抓取的网站进行抓取可能会使你进入他们的黑名单!与任何工具一样,Web 抓取也可能用于复制网站内容之类的不良目的。此外,由 Web 抓取引起的法律诉讼也不在少数。

设置代码

在充分了解小心行事的必要之后,让我们开始学习 Web 抓取。其实,Web 抓取可以通过任何编程语言实现,在不久之前,我们使用 Node 实现过。在本文中,考虑到其简洁性与丰富的包支持,我们将使用 Python 实现抓取程序。

Web 抓取的基本过程

当你打开网络中的某个站点时,就会下载其 HTML 代码,由你的 web 浏览器对其进行分析与展示。该 HTML 代码包含了你所看到的所有信息。因此,通过分析 HTML 代码就能得到所需信息(比如价格)。你可以使用正则表达式在数据海洋中搜索你需要的信息,也可以使用函数库来解释 HTML,同样也能得到需要数据。

在 Python 中,我们将使用一个名为靓汤(Beautiful Soup)的模块对 HTML 数据进行分析。你可以借助 pip 之类的安装程序安装之,运行如下代码即可:

pip install beautifulsoup4

或者,你也可以根据源码进行构建。在该模块的文档说明页,可以看到详细的安装步骤。

安装完成之后,我们大致会遵循以下步骤实现 web 抓取:

  • 向 URL 发送请求
  • 接收响应
  • 分析响应以寻找所需数据

作为演示,我们将使用笔者的博客 http://dada.theblogbowl.in/. 作为目标 URL。

前两个步骤相对简单,可以这样完成:

from urllib import urlopen#Sending the http requestwebpage = urlopen('http://my_website.com/').read()

接下来,将响应传给之前安装的模块:

from bs4 import BeautifulSoup#making the soup! yummy ;)soup = BeautifulSoup(webpage, "html5lib")

请注意,此处我们选择了 html5lib 作为解析器。根据 BeautifulSoup 的文档,你也可以为其选择不同的解析器。

解析 HTML

在将 HTML 传给 BeautifulSoup 之后,我们可以尝试一些指令。譬如,检查 HTML 标记代码是否正确,可以验证该页面的标题(在 Python 解释器中):

>>> soup.title<title>Transcendental  Tech Talk</title>>>> soup.title.text
u'Transcendental  Tech Talk'
>>>

接下来,开始抽取页面中的特定元素。譬如,我想抽取博客中文章标题的列表。为此,我需要分析 HTML 的结构,这一点可以借助 Chrome 检查器完成。其他浏览器也提供了类似的工具。

如何用 Python 实现 Web 抓取?
使用 Chrome 检查器检查某个页面的 HTML 结构

如你所见,所有文章标题都带有 h3 标签与两个类属性:post-titleentry-title 类。因此,用 post-title 类搜索所有 h3 元素就能得到该页的文章标题列表。在此例中,我们使用 BeautifulSoup 提供的 find_all 函数,并通过 class_ 参数确定所需的类:

>>> titles = soup.find_all('h3', class_ = 'post-title') #Getting all titles>>> titles[0].textu'\nKolkata #BergerXP IndiBlogger meet, Marketing Insights, and some Blogging Tips\n'>>>

只通过 post-title 类进行条目搜索应该可以得到相同的结果:

>>> titles = soup.find_all(class_ = 'post-title') #Getting all items with class post-title>>> titles[0].textu'\nKolkata #BergerXPIndiBlogger meet, Marketing Insights, and some Blogging Tips\n'>>>

如果你想进一步了解条目所指的链接,可以运行下面的代码:

>>> for title in titles:...     # Each title is in the form of <h3 ...><a href=...>Post Title<a/></h3>...     print title.find("a").get("href")...http://dada.theblogbowl.in/2015/09/kolkata-bergerxp-indiblogger-meet.html
http://dada.theblogbowl.in/2015/09/i-got-published.html
http://dada.theblogbowl.in/2014/12/how-to-use-requestput-or-requestdelete.html
http://dada.theblogbowl.in/2014/12/zico-isl-and-atk.html...>>>

BeautifulSoup 内置了许多方法,可以帮助你玩转 HTML。其中一些方法列举如下:

>>> titles[0].contents
[u'\n', <a href="http://dada.theblogbowl.in/2015/09/kolkata-bergerxp-indiblogger-meet.html">Kolkata #BergerXP IndiBlogger meet, Marketing Insights, and some Blogging Tips</a>, u'\n']>>>

请注意,你也可以使用 children 属性,不过它有点像生成器:

>>> titles[0].parent<div class="post hentry uncustomized-post-template">\n<a name="6501973351448547458"></a>\n<h3 class="post-title entry-title">\n<a href="http://dada.theblogbowl.in/2015/09/kolkata-bergerxp-indiblogger-meet.html">Kolkata #BergerXP IndiBlogger ...
>>>

你也可以使用正则表达式搜索 CSS 类,对此,本文档有详细的介绍。

使用 Mechanize 模拟登录

目前为止,我们做的只是下载一个页面进而分析其内容。然而,web 开发者可能屏蔽了非浏览器发出的请求,或者有些网站内容只能在登录之后读取。那么,我们该如何处理这些情况呢?

对于第一种情况,我们需要在向页面发送请求时模拟一个浏览器。每个 HTTP 请求都包含一些相关的数据头(header),其中包含了访客浏览器、操作系统以及屏幕大小之类的信息。我们可以改变这些数据头,伪装为浏览器发送请求。

至于第二种情况,为了访问带有访客限制的内容,我们需要登录该网站,使用 cookie 保持会话。下面,让我们来看看在伪装成浏览器的同时,如何完成这一点。

我们将借助 cookielib 模块使用 cookie 管理会话。此外,我们还将用到 mechanize,后者可以使用 pip 之类的安装程序进行安装。

我们会通过 Blog Bowl 这个页面进行登录,并访问通知页面。下面的代码通过行内注释进行了解释:

import mechanize
import cookielibfrom urllib import urlopen
from bs4 import BeautifulSoup# Cookie Jarcj = cookielib.LWPCookieJar()browser = mechanize.Browser()
browser.set_cookiejar(cj)
browser.set_handle_robots(False)
browser.set_handle_redirect(True)# Solving issue #1 by emulating a browser by adding HTTP headersbrowser.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')]# Open Login Pagebrowser.open("http://theblogbowl.in/login/")# Select Login form (1st form of the page)browser.select_form(nr = 0)# Alternate syntax - browser.select_form(name = "form_name")# The first <input> tag of the form is a CSRF token# Setting the 2nd and 3rd tags to email and passwordbrowser.form.set_value("email@example.com", nr=1)
browser.form.set_value("password", nr=2)# Logging inresponse = browser.submit()# Opening new page after loginsoup = BeautifulSoup(browser.open('http://theblogbowl.in/notifications/').read(), "html5lib")

如何用 Python 实现 Web 抓取?
通知页面的结构

# Print notificationsprint soup.find(class_ = "search_results").text

如何用 Python 实现 Web 抓取?
登录进通知页面后的结果

结语

许多开发者会告诉你:你在网络上看到的任何信息都可以被抓取。通过这篇文章,你学会了如何轻松抽取登录后才能看到的内容。此外,如果你的 IP 遭到了屏蔽,你可以掩盖自己的 IP 地址(或选用其他地址)。同时,为了看起来像是人类在访问,你应该在请求之间保留一定的时间间隔。

随着人们对数据的需求不断增长,web 抓取(不论原因好坏)技术在未来的应用只会更加广泛。也因此,理解其原理是相当重要的,不管你是为了有效利用该技术,还是为了免受其坑害。

OneAPM 能帮您查看 Python 应用程序的方方面面,不仅能够监控终端的用户体验,还能监控服务器性能,同时还支持追踪数据库、第三方 API 和 Web 服务器的各种问题。想技术文章,请访问 OneAPM 官方技术博客。

本文转自 OneAPM 官方博客

原文地址:https://www.sitepoint.com/web-scraping-for-beginners/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/398244.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

sentinel 不显示项目_Sentinel+Nacos实现资源流控、降级、热点、授权

本文同名博客老炮说Java&#xff1a;https://www.laopaojava.com/&#xff0c;每天更新Spring/SpringMvc/SpringBoot/实战项目等文章资料SentinelNacos 是微服务环境搭建必不可少的两个组件&#xff0c;这里给大家推荐一套微服务教程&#xff1a;SpringCloud微服务电商项目教程…

斗地主你什么时候才会托管?(.NET中的托管于非托管)

文章部分引自《.NET4.0面向对象编程漫谈&#xff08;基础篇&#xff09;》第1章.NET面向对象编程基础&#xff08;作者&#xff1a;金旭亮&#xff09; 无意间看到一位四五岁左右小朋友在玩斗地主&#xff0c;总开始到结束&#xff0c;她一直都在使用“提示”&#xff08;托管&…

英特尔固态硬盘540s开卡_英特尔Z490主板绝配?技嘉PCIe 3.0 x8固态硬盘测试:6.5GB/s读速...

PCIe 4.0为高端NVMe固态硬盘提供了更广阔的提升空间&#xff0c;而暂时与PCIe 4.0无缘的英特尔平台就比较尴尬。技嘉推出的AORUS RAID SSD似乎正是为此而生&#xff0c;它以PCIe 3.0 x8接口提供6500MB/s顺序读取和6000MB/s顺序写入速度&#xff0c;足以媲美尚未面世的第二代PCI…

李洪强-C语言2-字符串

C语言字符串 一、字符串基础 注意&#xff1a;字符串一定以\0结尾。 Printf(“yang\n”); 其中yang为字符串常量&#xff0c;“yang”‘y’‘a’‘n’‘g’‘\0’。字符串由很多的字符组成&#xff0c;通常使用字符数组来存储字符串&#xff0c;如char name[10]“yang”;也可以…

【练习5.9】图像掩码、礼帽、cvCopy、图像融合、cvCvtColor

提纲题目要求程序代码结果图片要言妙道题目要求&#xff1a; 读入一副风景图&#xff0c;然后将其转化为灰度图像 a、对图像进行形态学“礼帽”操作&#xff0c;并显示结果 b、将结果图像转化为8位的掩码 c、复制灰度值到礼帽块中&#xff0c;显示结果→我的理解是&#xff0c;…

div超出不换行_文字超出显示点点点之ellipsis 设置

一般情况下一行文字在一定区域显示的话如果不限定高度&#xff0c;那么在内容超过的宽度的话就会换行显示&#xff0c;为了页面的美观&#xff0c;目前的通用做法就是在最后显示…&#xff0c;然后鼠标悬浮显示完整内容&#xff0c;具体设置如下:height: 40px; overflor: hidde…

Kali源库配置和拼音安装

2019独角兽企业重金招聘Python工程师标准>>> 版本&#xff1a;kali-linux-2016.1-i386 0、对kali进行系统更新或者软件安装&#xff0c;直接通过国内网络访问境外主网网络不稳定&#xff0c;不如改成国内资源站点。 1、修改以下文档 vim /etc/apt/sources.list 2、文…

java中审核订单流程图_Java 后端横扫阿里、滴滴、美团总结的面试经验!

这次面试的公司有一点点多&#xff0c;主要是因为毕业后前两份工作找的都很草率&#xff0c;这次换工作就想着&#xff0c;emm&#xff0c;毕业三年了&#xff0c;该找个工作好好沉淀几年了。先说下这次面试的结果吧&#xff1a;到 hr 面的&#xff1a;阿里、美团、滴滴、金山云…

产品铭牌要求_AMPULM:电力变压器铭牌有哪些主要技术参数,你都知道吗?

电力变压器电力变压器是供配电系统中关键的一个环节&#xff0c; 它起到电力系统中电压等级的变换&#xff0c;同时连接不同电压等级的电网&#xff0c;以利于电能的输送、分配和使用。认识变压器铭牌图片为一台电力变压器上的铭牌&#xff0c;从铭牌上可以看到变压器的哪些信息…

python 学习资源收集汇总

2019独角兽企业重金招聘Python工程师标准>>> Python是一种面向对象、直译式计算机程序设计语言。它的语法简捷和清晰&#xff0c;尽量使用无异义的英语单词&#xff0c;与其它大多数程序设计语言使用大括号不一样&#xff0c;它使用縮进来定义语句块。与Scheme、Rub…

一年月份大小月口诀_怎么看自己的日柱 公式 推算口诀 最简便计算方法

日柱指的是我们农历干支出生的那一天&#xff0c;通过日柱我们可以看出自己命运的轨迹和走向&#xff0c;从风水学上来讲日柱是八字算命中举足轻重的一部分&#xff0c;那么如何知道自己的日柱呢&#xff1f;通过本期的四柱预测&#xff0c;给大家介绍一种最简便的推算口诀和日…

delphi excel取批注所在的行列_35个Excel使用技巧

技巧1、单元格内强制换行在单元格中某个字符后按alt回车键&#xff0c;即可强制把光标换到下一行中。技巧2、锁定标题行选取第2行&#xff0c;视图 - 冻结窗格 - 冻结首行(或选取第2行 - 冻结窗格)冻结后再向下翻看时标题行始终显示在最上面。技巧3、打印标题行如果想在打印时每…

如何接收串口数据_UART IDLE 中断使用接收不定长串口数据

前言在串口通信应用中&#xff0c;我们常使用接受和发送中断&#xff0c;相信大家都不陌生。这里有个非常有用的中断可能被大家所忽略&#xff0c;即总线IDLE中断。当一帧数据传输结束之后&#xff0c;总线会维持高电平状态&#xff0c;此时&#xff0c;就可以触发MCU的IDLE中断…

MFC 进度条CProgressCtrl

2019独角兽企业重金招聘Python工程师标准>>> SetStep(1);//设置步长 SetRange32(0, total);//设置范围 SetPos(_cur);//设置当前 进度 StepIt();进步一次 转载于:https://my.oschina.net/kkkkkkkkkkkkk/blog/688392

css限制字体三行_讲道理,仅3行核心css代码的rate评分组件,我被自己秀到头皮发麻...

(给100素材网点亮★号&#xff0c;提升开发技能)像rate评分组件一般都用javascript写&#xff0c;所以这次将是一个全新的尝试&#xff0c;用css实现一个rate评分 ❗ 核心代码也就三行?01效果图02原理主要是借助radio单选框&#xff0c;梳理如下&#xff1a;去找个好看的iconf…

matlab GUI之自定义菜单小结

自定义菜单 1.uimenu对象 huimenu(PropertyName,ProperValue) huimenu(parent,PropertyName,ProperValue) 常见属性&#xff1a; 1.1标签 label uimenu(label,&Open) 1.2快捷键 Accelerator uimenu(Accelerator,E) 快捷键位 ctrlE 注意以下三个是系统保留的Accelerator…

把cpp编译为so_基于VSCode和CMake进行C/C++开发第三讲GCC编译器

3.0 本讲目录本系列视频&#xff0c;B站首发&#xff0c;up主: xiaobing1016前言&#xff1a;GCC 编译器支持编译 Go、Objective-C&#xff0c;Objective-C &#xff0c;Fortran&#xff0c;Ada&#xff0c;D 和 BRIG(HSAIL)等程序&#xff1b;Linux 开发C/C 一定要熟悉 GCCVS…

CSS快速入门-箭头和图标

一、三步搞懂箭头产生的原理 在前面的盒子模型一文中&#xff0c;我们已经知道了一个元素空间占位。为了弄明白箭头的产生&#xff0c;我们可以三步走&#xff1a; #demo12 {border: 100px solid;border-color:green blue orange red;width:100px;height:100px;}<div id&quo…

自动清理归档日志_从MYSQL 数据库归档 到 归档设计

到数据归档&#xff0c;很多人的第一个概念就是&#xff0c;不就是无用的数据&#xff0c;换个地方放吗&#xff0c;直接拷贝&#xff0c;删除不就得了&#xff0c;有那么麻烦。我见到过的&#xff0c;听到过的数据库归档的方法有以下几种1 数据通过人工的手段来进行清理&…

Android支付宝SDK开发笔记

一、准备工作 〉1、下载开发包 https://b.alipay.com/order/productDetail.htm?productId2014110308141993&tabId4#ps-tabinfo-hash 压缩包下的“支付宝钱包支付接口开发包”中即有Andoid使用支付宝的JAR和Demo 〉2、创建支付宝应用 在支付宝开放平台申请创建应用 https:/…