关于python:Python-爬虫实战驾驭数据洪流揭秘网页深处

113次阅读

共计 5009 个字符,预计需要花费 13 分钟才能阅读完成。

爬虫,这个常常被人提到的词,是对数据收集过程的一种形象化形容。特地是在 Python 语言中,因为其丰盛的库资源和良好的易用性,使得其成为编写爬虫的绝佳抉择。本文将从基础知识开始,深入浅出地解说 Python 爬虫的相干常识,并分享一些独特的用法和实用技巧。本文将以理论的网站为例,深刻论述各个解决局部,并展现输入,助力大家疾速把握 Python 爬虫技巧。

开始之前:必要的库

Python 有很多库能够用来编写爬虫,但咱们这里重点介绍两个:requests 和 BeautifulSoup。

import requests
from bs4 import BeautifulSoup

requests库用于发送 HTTP 申请,而 BeautifulSoup 库则用于解析 HTTP 响应中的 HTML。

根本爬虫:爬取全副网页内容

以 Python 官方网站(https://www.python.org/)为例,一个根本的 Python 爬虫可能会这样编写:

url = "https://www.python.org/"
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')
print(soup.prettify()[:500])

这段代码的目标是获取网页的内容,并应用 BeautifulSoup 库进行解析。咱们能够看到,requests.get(url)是用来发送 GET 申请的,而 BeautifulSoup(response.text, 'html.parser') 则是用来解析 HTTP 响应中的 HTML 内容的。

这段代码的输入前 500 个字符如下:

<!DOCTYPE html>
<!--[if lt IE 7]>   <html class="no-js ie6 lt-ie7 lt-ie8 lt-ie9">   <![endif]-->
<!--[if IE 7]>      <html class="no-js ie7 lt-ie8 lt-ie9">          <![endif]-->
<!--[if IE 8]>      <html class="no-js ie8 lt-ie9">                 <![endif]-->
<!--[if gt IE 8]><!--><html class="no-js" dir="ltr" lang="en">  <!--<![endif]-->
<head>
<meta charset="utf-8"/>
<meta content="IE=edge" http-equiv="X-UA-Compatible"/>
<meta content="Python.org" name="application-name"/>
<meta content="The official home of the Python Programming Language" 

应用 CSS 选择器爬取特定元素

当咱们心愿获取特定元素时,咱们能够应用 CSS 选择器。比方咱们心愿获取 Python 官方网站中所有的头部链接:

elements = soup.select('div.top-bar > ul > li > a')
for element in elements:
    print(element.get('href'), element.text)

在这里,div.top-bar > ul > li > a是一个 CSS 选择器,用来抉择

class 为 top-bar 的 div 元素下的 ul 元素中的 li 元素下的 a 元素。这些 a 元素就是咱们想要的头部链接。

这段代码的局部输入如下:

/ Python
/psf-landing/ PSF
/docs/ Docs
/pypl/ PyPI
/jobs/ Jobs
/community-landing/ Community

HTML 解析语言爬取:XPath

除了 CSS 选择器,还有一种罕用的 HTML 解析技术是 XPath。XPath,全称 XML Path Language,是一门在 XML 文档中查找信息的语言,也能够用在 HTML 文档解析中。

Python 的 lxml 库提供了 XPath 的反对:

from lxml import etree

html = '<div><a href="/a">A</a><a href="/b">B</a></div>'
root = etree.HTML(html)

links = root.xpath('//a/@href')
print(links)

在这段代码中,咱们首先定义了一个 HTML 字符串。而后,咱们应用 etree.HTML() 函数将这个字符串解析成一个 DOM 树。最初,咱们应用 root.xpath() 办法提取出所有的链接。

相对链接爬取

你可能曾经留神到,上述代码的输入中的链接是绝对链接,而不是相对链接。如果咱们心愿获取相对链接,咱们能够应用 urljoin 函数:

from urllib.parse import urljoin

elements = soup.select('div.top-bar > ul > li > a')
for element in elements:
    absolute_url = urljoin(url, element.get('href'))
    print(absolute_url, element.text)

这段代码的局部输入如下:

https://www.python.org/ Python
https://www.python.org/psf-landing/ PSF
https://www.python.org/docs/ Docs
https://www.python.org/pypl/ PyPI
https://www.python.org/jobs/ Jobs
https://www.python.org/community-landing/ Community

动静加载的数据爬取:Selenium

在许多古代的网页中,数据可能不是在页面加载时一次性加载的,而是通过 JavaScript 在用户与页面交互时动静加载的。这时,咱们可能须要应用另一个工具:Selenium。

from selenium import webdriver

driver = webdriver.Firefox()
driver.get('https://www.python.org/')

element = driver.find_element_by_css_selector('div.top-bar > ul > li > a')
print(element.text)

这段代码应用 Selenium 模仿浏览器行为,获取 JavaScript 动静加载的数据。在这个例子中,咱们只获取了第一个链接的文本,理论应用时,你可能须要依据需要进行更简单的操作。

爬虫代理

应用代理,能够帮忙咱们暗藏本人的实在 IP 地址,从而防止因爬取同一网站过多数据而被封 IP。上面是一段简略的应用代理的代码:

proxies = {
    "http": "http://10.10.1.10:3128",
    "https": "http://10.10.1.10:1080",
}

response = requests.get("https://www.python.org/", proxies=proxies)

在这里,咱们定义了一个代理字典,并将其传给 requests.get() 函数。这样,咱们的申请就会通过代理服务器发送,从而暗藏了咱们的实在 IP 地址。

异步爬虫:晋升爬虫效率

在爬取大量数据时,咱们通常须要进行屡次 HTTP 申请,如果每次申请都期待前一次申请实现,那么效率将会非常低。此时,咱们能够应用 Python 的异步 IO 库 asyncioaiohttp来提高效率。上面是一个简略的例子:

import asyncio
import aiohttp

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, 'http://python.org')
        print(html[:500])

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

在这段代码中,咱们首先定义了一个异步的 fetch 函数,用于发送 HTTP 申请并获取响应。而后,咱们在 main 函数中创立一个 HTTP 会话,并应用这个会话来发送申请。最初,咱们应用事件循环来运行 main 函数。

爬虫框架:Scrapy

尽管应用上述办法能够实现爬虫的基本功能,但在解决更简单的爬虫工作时,咱们可能须要一个更弱小的工具。Scrapy 是一个用 Python 实现的弱小的爬虫框架,它为咱们提供了许多高级性能,比方并发申请、数据处理和存储等。

上面是一个简略的 Scrapy 爬虫的例子:

import scrapy

class MySpider(scrapy.Spider):
    name = 'myspider'
    start_urls = ['http://python.org']

    def parse(self, response):
        self.log('Visited %s' % response.url)
        yield {
            'url': response.url,
            'title': response.css('title::text').get(),}

在这段代码中,咱们定义了一个继承自 scrapy.Spider 的爬虫类。这个类中定义了爬虫的名字、开始的 URL 和解析响应的办法。Scrapy 将会主动为咱们解决申请的发送和响应的接管,咱们只须要关怀如何从响应中提取数据即可。

自动化工作:定时爬虫

有时咱们须要定时执行爬虫工作,比方每天爬取一次网站的数据。Python 的 schedule 库能够帮忙咱们实现这一点:

import schedule
import time

def job():
    print("I'm working...")

schedule.every(10).seconds.do(job)

while True:
    schedule.run_pending()
    time.sleep(1)

在这段代码中,咱们首先定义了一个爬虫工作 job。而后,咱们应用schedule.every().seconds.do() 办法设置工作的执行距离。最初,咱们应用一个有限循环来一直执行待运行的工作。

爬虫道德规范:恪守 robots.txt

在进行爬虫时,咱们须要尊重网站的 robots.txt 规定。robots.txt是一个寄存在网站根目录下的文本文件,用于通知爬虫哪些页面能够抓取,哪些页面不能够抓取。

Python 的 urllib.robotparser 模块能够帮忙咱们解析robots.txt

from urllib.robotparser import RobotFileParser

rp = RobotFileParser()
rp.set_url('http://www.python.org/robots.txt')
rp.read()

can_fetch = rp.can_fetch('*', 'http://www.python.org/')
print(can_fetch)

在这段代码中,咱们首先创立了一个 RobotFileParser 对象,而后应用 set_url 办法设置 robots.txt 的 URL,并应用 read 办法读取和解析 robots.txt。最初,咱们应用can_fetch 办法判断咱们的爬虫是否能够抓取指定的 URL。

请留神,不是所有的网站都有robots.txt,也不是所有的网站都会严格遵守robots.txt。在爬取网站时,除了尊重robots.txt,咱们还应该尽量减小爬虫对网站的影响,例如限度爬取频率,防止在网站高访问量的时候爬取。

总结

总结起来,Python 爬虫尽管有许多简单的技术和知识点,但只有把握了基础知识和一些实用技巧,就能够解决大部分的爬虫工作。将来,我将持续分享更多的 Python 爬虫常识和技巧。

如有帮忙,请多关注
集体微信公众号:【Python 全视角】
TeahLead_KrisChang,10+ 年的互联网和人工智能从业教训,10 年 + 技术和业务团队治理教训,同济软件工程本科,复旦工程治理硕士,阿里云认证云服务资深架构师,上亿营收 AI 产品业务负责人。

正文完
 0