资讯专栏INFORMATION COLUMN

使用Python开始Web Scraping

fobnn / 2232人阅读

摘要:主要元素是身体内容,可以表示为。提取每个元素的文本并最终组成单个文本。我们将使用故意慢的服务器来显示这一点。是表示值的承诺的对象。我们将使用仓库中提供的准备示例作为示例。请注意,其余代码基本上不受影响除了返回函数中的源链接。

来源 | 愿码(ChainDesk.CN)内容编辑

愿码Slogan | 连接每个程序员的故事

网站 | http://chaindesk.cn

愿码愿景 | 打造全学科IT系统免费课程,助力小白用户、初级工程师0成本免费系统学习、低成本进阶,帮助BAT一线资深工程师成长并利用自身优势创造睡后收入。

官方公众号 | 愿码 | 愿码服务号 | 区块链部落

免费加入愿码全思维工程师社群 | 任一公众号回复“愿码”两个字获取入群二维码


本文阅读时长:15min

在本文中,我们将学习以编程方式执行操作以自动检索和处理信息。Python  requests模块使得执行这些操作变得非常容易。
本文知识点:

下载网页

解析HTML

抓取网络

访问受密码保护的页面

加快网络抓取速度

下载网页

下载网页的基本功能包括GET针对URL 发出HTTP 请求。这是任何Web浏览器的基本操作。我们将在此配方中看到如何获取获取网页的简单请求。

安装  requests模块:

$ echo "requests==2.18.3" >> requirements.txt
$ source .venv/bin/activate
(.venv) $ pip install -r requirements.txt
如何下载网页

导入requests模块:

>>> import requests

请求URL,这需要一两秒钟:

>>> url = "http://www.columbia.edu/~fdc/sample.html"
>>> response = requests.get(url)

检查返回的对象状态代码:

>>> response.status_code
200

检查结果的内容:

>>> response.text
"



...
FULL BODY
...

"

检查正在进行的和返回的标题:

>>> response.request.headers
{"User-Agent": "python-requests/2.18.4", "Accept-Encoding": "gzip, deflate", "Accept": "*/*", "Connection": "keep-alive"}
>>> response.headers
{"Date": "Fri, 25 May 2018 21:51:47 GMT", "Server": "Apache", "Last-Modified": "Thu, 22 Apr 2004 15:52:25 GMT", "Accept-Ranges": "bytes", "Vary": "Accept-Encoding,User-Agent", "Content-Encoding": "gzip", "Content-Length": "8664", "Keep-Alive": "timeout=15, max=85", "Connection": "Keep-Alive", "Content-Type": "text/html", "Set-Cookie": "BIGipServer~CUIT~www.columbia.edu-80-pool=1764244352.20480.0000; expires=Sat, 26-May-2018 03:51:47 GMT; path=/; Httponly"}

操作requests非常简单; GET在这种情况下,通过URL 执行操作。这将返回result可以分析的对象。主要元素是status_code身体内容,可以表示为text。

可以在request现场检查完整请求:

>>> response.request

>>> response.request.url
"http://www.columbia.edu/~fdc/sample.html"
解析HTML

我们将使用Beautiful Soup模块将HTML文本解析为可以分析的内存对象。我们需要使用该  beautifulsoup4 包来使用可用的Python 3版本。将软件包添加到您requirements.txt的虚拟环境中并安装依赖项:

$ echo "beautifulsoup4==4.6.0" >> requirements.txt
$ pip install -r requirements.txt
如何执行HTML解析

导入BeautifulSoup和requests:

>>> import requests
>>> from bs4 import BeautifulSoup

设置要下载和检索的页面的URL:

>>> URL = "http://www.columbia.edu/~fdc/sample.html"
>>> response = requests.get(URL)
>>> response

解析下载的页面:

>>> page = BeautifulSoup(response.text, "html.parser")

获取页面标题。看到它与浏览器中显示的内容相同:

>>> page.title
Sample Web Page
>>> page.title.string
"Sample Web Page"

查找h3页面中的所有元素,以确定现有部分:

>>> page.find_all("h3") [CONTENTS, 1. Creating a Web Page, 2. HTML Syntax, 3. Special Characters, 4. Converting Plain Text to HTML, 5. Effects, 6. Lists, 7. Links, 8. Tables, 9. Installing Your Web Page on the Internet, 10. Where to go from here]

提取部分链接上的文本。当你到达下一个时停止

标签:

>>> link_section = page.find("a", attrs={"name": "links"})
>>> section = []
>>> for element in link_section.next_elements:
...     if element.name == "h3":
...         break
...     section.append(element.string or "")
...
>>> result = "".join(section)
>>> result
"7. Links

Links can be internal within a Web page (like to
the Table of ContentsTable of Contents at the top), or they
can be to external web pages or pictures on the same website, or they
can be to websites, pages, or pictures anywhere else in the world.



Here is a link to the Kermit
Project home pageKermit
Project home page.



Here is a link to Section 5Section 5 of this document.



Here is a link to
Section 4.0Section 4.0
of the C-Kermit
for Unix Installation InstructionsC-Kermit
for Unix Installation Instructions.



Here is a link to a picture:
CLICK HERECLICK HERE to see it.


"

请注意,没有HTML标记; 这都是原始文本。

第一步是下载页面。然后,可以解析原始文本,如步骤3所示。结果  page 对象包含解析的信息。BeautifulSoup允许我们搜索HTML元素。它可以搜索第一个.find() 或返回列表  .find_all()。在步骤5中,它搜索具有特定属性的特定标签name=link。之后,它继续迭代,.next_elements直到找到下一个h3标记,标记该部分的结尾。

提取每个元素的文本并最终组成单个文本。请注意or,避免存储None,当元素没有文本时返回。

抓取网络

鉴于超链接页面的性质,从一个已知的地方开始,并在链接到其他页面后,在抓取网络时,这是一个非常重要的工具。

为此,我们抓取一个寻找小短语的页面,并打印包含它的任何段落。我们只会搜索属于同一网站的网页。即只有以www.somesite.com开头的网址。我们不会关注指向外部网站的链接。

我们将使用GitHub仓库中提供的准备示例作为示例。 下载整个站点并运行包含的脚本。

$ python simple_delay_server.py

这为URL中的站点提供服务http://localhost:8000。您可以在浏览器上查看它。这是一个有三个条目的简单博客。大部分都是无趣的,但我们添加了几个包含关键字的段落python。

如何抓取网络

完整的脚本crawling_web_step1.py可以在GitHub中找到。这里显示最相关的位:

...
def process_link(source_link, text):
    logging.info(f"Extracting links from {source_link}")
    parsed_source = urlparse(source_link)
    result = requests.get(source_link)
    # Error handling. See GitHub for details
    ...
    page = BeautifulSoup(result.text, "html.parser")
    search_text(source_link, page, text)
    return get_links(parsed_source, page)

def get_links(parsed_source, page):
    """Retrieve the links on the page"""
    links = []
    for element in page.find_all("a"):
        link = element.get("href")
        # Validate is a valid link. See GitHub for details
        ...
        links.append(link)
    return links

搜索引用python,以返回包含包含它的URL和段落的列表。请注意,由于链接断开,存在一些错误:

$ python crawling_web_step1.py https://localhost:8000/ -p python
Link http://localhost:8000/: --> A smaller article , that contains a reference to Python
Link http://localhost:8000/files/5eabef23f63024c20389c34b94dee593-1.html: --> A smaller article , that contains a reference to Python
Link http://localhost:8000/files/33714fc865e02aeda2dabb9a42a787b2-0.html: --> This is the actual bit with a python reference that we are interested in.
Link http://localhost:8000/files/archive-september-2018.html: --> A smaller article , that contains a reference to Python
Link http://localhost:8000/index.html: --> A smaller article , that contains a reference to Python

另一个很好的搜索词是crocodile。试试看:

$ python crawling_web_step1.py http://localhost:8000/ -p crocodile

让我们看看脚本的每个组件:

在main函数中遍历所有找到的链接的循环:

在process_link函数中下载和解析链接:

它会下载文件,并检查状态是否正确,以跳过链接断开等错误。它还会检查类型(如上所述  Content-Type)是否为HTML页面以跳过PDF和其他格式。最后,它将原始HTML解析为一个BeautifulSoup对象。

它还使用解析源链接urlparse,因此稍后在步骤4中,它可以跳过对外部源的所有引用。 urlparse将URL划分为其组成元素:

>>> from urllib.parse import urlparse
>>> >>> urlparse("http://localhost:8000/files/b93bec5d9681df87e6e8d5703ed7cd81-2.html")
ParseResult(scheme="http", netloc="localhost:8000", path="/files/b93bec5d9681df87e6e8d5703ed7cd81-2.html", params="", query="", fragment="")

它在search_text函数中找到要搜索的文本:

它在解析的对象中搜索指定的文本。请注意,搜索仅作为a regex并在文本中完成。它打印生成的匹配项,包括source_link引用找到匹配项的URL:

for element in page.find_all(text=re.compile(text)):
    print(f"Link {source_link}: --> {element}")

该get_links 函数检索页面上的所有链接:

它在解析的页面中搜索所有元素,并检索href元素,但仅检索具有此类href元素且是完全限定URL(以...开头http)的元素。这将删除不是URL的"#"链接,例如链接或页面内部的链接。

进行额外检查以检查它们是否与原始链接具有相同的来源,然后将它们注册为有效链接。该netloc属性允许检测链接来自与步骤2中生成的已解析URL相同的URL域。

最后,返回链接,将它们添加到步骤1中描述的循环中。

访问受密码保护的页面

有时网页不向公众开放,但以某种方式受到保护。最基本的方面是使用基本的HTTP身份验证,它几乎集成到每个Web服务器中,它是一个用户/密码架构。

我们可以在https://httpbin.org中测试这种...  。它有一个路径,/basic-auth/{user}/{password}强制进行身份验证,并指定用户和密码。这对于理解身份验证的工作原理非常方便。

如何访问受密码保护的页面

进口requests:

>>> import requests

做一个GET与错误的凭据的URL请求。请注意,我们将URL上的凭据设置为:user 和psswd:

>>> requests.get("https://httpbin.org/basic-auth/user/psswd", 
                 auth=("user", "psswd"))

使用错误的凭据返回401状态代码(未授权):

>>> requests.get("https://httpbin.org/basic-auth/user/psswd", 
                 auth=("user", "wrong"))

凭证也可以直接在URL中传递,@在服务器之前用冒号和符号分隔,如下所示:

>>> requests.get("https://user:psswd@httpbin.org/basic-auth/user/psswd")

>>> requests.get("https://user:wrong@httpbin.org/basic-auth/user/psswd")
加快网络抓取速度

从网页下载信息所花费的大部分时间通常都在等待。一个请求从我们的计算机发送到任何服务器将处理它,直到响应组成并返回到我们的计算机,我们不能做太多的事情。

在本文中,我们将看到如何并行下载页面列表,并等待它们全部准备好。我们将使用故意慢的服务器来显示这一点。

我们将获取用于抓取和搜索关键字的代码,利用futuresPython 3 的功能同时下载多个页面。A future是表示值的承诺的对象。这意味着您在后台执行代码时会立即收到对象。只有在特别要求其.result()代码块时才能获得它。

要生成a future,您需要一个名为executor的后台引擎。一旦创建,就会 submit有一个函数和参数来检索它future。结果的检索可以根据需要延迟,允许futures连续生成几个,并等待所有结束,并行执行它们,而不是创建一个,等到它完成,创建另一个,依此类推。

有几种方法可以创建执行程序; 我们将使用ThreadPoolExecutor,它将使用线程。

我们将使用GitHub仓库中提供的准备示例作为示例。下载整个站点并运行包含的脚本

$ python simple_delay_server.py -d 2

这为URL中的站点提供服务  http://localhost:8000。您可以在浏览器上查看它。这是一个简单的博客,有三个条目。大部分都是无趣的,但我们添加了几个包含关键字的段落  python。该参数-d 2使服务器故意变慢,模拟连接错误。

如何加快网页抓取速度

编写以下脚本speed_up_step1.py。完整代码可在GitHub中找到。

注意main功能的差异。此外,还添加了一个额外的参数(并发工作者数),该函数process_link 现在返回源链接。

运行  crawling_web_step1.py 脚本以获取时间基准。请注意,为清楚起见,此处已删除输出:

$ time python crawling_web_step1.py http://localhost:8000/
... REMOVED OUTPUT
real 0m12.221s
user 0m0.160s
sys 0m0.034s

使用一个工作程序运行新脚本,该工作程序比原始工作程序慢:

$ time python speed_up_step1.py -w 1
... REMOVED OUTPUT
real 0m16.403s
user 0m0.181s
sys 0m0.068s

增加工人数量:

$ time python speed_up_step1.py -w 2
... REMOVED OUTPUT
real 0m10.353s
user 0m0.199s
sys 0m0.068s

添加更多工作人员会减少时间:

$ time python speed_up_step1.py -w 5
... REMOVED OUTPUT
real 0m6.234s
user 0m0.171s
sys 0m0.040s

创建并发请求的主要引擎是主要功能。请注意,其余代码基本上不受影响(除了返回process_link函数中的源链接)。这是处理并发引擎的代码的相关部分:

with concurrent.futures.ThreadPoolExecutor(max_workers=workers) as executor:
    while to_check:
        futures = [executor.submit(process_link, url, to_search)
                   for url in to_check]
        to_check = []
        for data in concurrent.futures.as_completed(futures):
            link, new_links = data.result()
             checked_links.add(link)
            for link in new_links:
                if link not in checked_links and link not in to_check:
                    to_check.append(link)

             max_checks -= 1
             if not max_checks:
                return

该with背景下产生的工人池,并指定其编号。在内部,创建包含要检索的所有URL的期货列表。该.as_completed()函数返回已完成的期货,然后有一些工作处理获取新找到的链接并检查是否需要添加它们以进行检索。此过程类似于抓取Web 配方中显示的过程。

该过程再次开始,直到检索到足够的链接或没有要检索的链接。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/43806.html

相关文章

  • 忘记API 使用Beautiful Soup进行Python Scraping,从Web导入数据文件

    摘要:忘记使用进行,从导入数据文件第部分对于每个网站而言,并不总是适合您,但将永远与您保持联系以从任何网站收集任何类型的数据。非资源让我们拿一个维基百科页面进行报废。请求它旨在被人类用于与语言进行通信。使用标签,我们将告诉保护我们的数据。忘记API使用Beautiful Soup进行Python Scraping,从Web导入数据文件:第2部分 对于每个网站而言,API并不总是适合您,但Be...

    马龙驹 评论0 收藏0
  • 忘记API 使用Beautiful Soup进行Python Scraping,从Web导入数据文件

    摘要:忘记使用进行,从导入数据文件第部分对于每个网站而言,并不总是适合您,但将永远与您保持联系以从任何网站收集任何类型的数据。非资源让我们拿一个维基百科页面进行报废。请求它旨在被人类用于与语言进行通信。使用标签,我们将告诉保护我们的数据。忘记API使用Beautiful Soup进行Python Scraping,从Web导入数据文件:第2部分 对于每个网站而言,API并不总是适合您,但Be...

    wayneli 评论0 收藏0
  • 小程序开发(一):使用scrapy爬虫采集数据

    摘要:用途广泛,可以用于数据挖掘监测和自动化测试。运行下,发现数据全部存到了数据库中。提供了一些接口来查看项目爬虫情况,以及执行或者停止执行爬虫。完成小程序所需要的所有接口的开发,以及使用定时任务执行爬虫脚本。 过完年回来,业余时间一直在独立开发一个小程序。主要数据是8000+个视频和10000+篇文章,并且数据会每天自动更新。 我会整理下整个开发过程中遇到的问题和一些细节问题,因为内容会比...

    mrli2016 评论0 收藏0
  • 如何用 Python 实现 Web 抓取?

    摘要:许多网站在其服务条款中明确禁止对其内容进行抓取。此外,由抓取引起的法律诉讼也不在少数。在本文中,考虑到其简洁性与丰富的包支持,我们将使用实现抓取程序。在中,我们将使用一个名为靓汤的模块对数据进行分析。 【编者按】本文作者为 Blog Bowl 联合创始人 Shaumik Daityari,主要介绍 Web 抓取技术的基本实现原理和方法。文章系国内 ITOM 管理平台 OneAPM 编译...

    yanwei 评论0 收藏0
  • 10、web爬虫讲解2—Scrapy框架爬虫—Scrapy安装—Scrapy指令

    摘要:负责处理被提取出来的。典型的处理有清理验证及持久化例如存取到数据库知识库项目的设置文件实现自定义爬虫的目录中间件是在引擎及之间的特定钩子,处理的输入和输出及。 【百度云搜索:http://www.bdyss.com】 【搜网盘:http://www.swpan.cn】 Scrapy框架安装 1、首先,终端执行命令升级pip: python -m pip install --upgrad...

    OnlyMyRailgun 评论0 收藏0

发表评论

0条评论

fobnn

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<