如何使用Python快速抓取许多HTML文档?

时间:2019-07-08 04:05:40

标签: python html parsing web-scraping scrapy

我有大约100个HTML网页的列表(所有网页都有不同的结构,例如div,锚点,类等),我正在尝试抓取每个页面的标题(标题在某个div和类)。为此,我使用了get请求和Beautifulsoup,但是,这花了很长时间(每次我想做10分钟)!

我使用计时器来查看花费最多的时间:这是获取请求。显然,Python(3.7)一次又一次地执行代码,并且由于每个get请求大约需要5-6秒,因此完成大约100个请求大约需要500-600秒。

我一直在寻找使这些请求更快运行的方法,并且遇到了许多不同的解决方案。但是,一个共同的主题似乎是使我的请求异步(因此所有请求都同时启动)将解决问题(通过使其更快)。

我在网上阅读了许多可能的解决方案,包括:多线程,使用grequest,使用Scrapy,解析lxml等。但是,我是编程的新手,对每种方法的学习和试验都不够熟练(实际上,我尝试遵循SO上类似问题的答案,但没有成功),所以我不确定什么是我最好的选择。

我不需要任何幻想;我要做的就是从HTML文档中将标题提取为文本,然后将其打印出来。我不需要下载任何CSS文件,图像,媒体等。此外,我希望代码尽可能简单/裸露。如何在Python中尽快完成此操作?如果有人可以提出最佳方法(即使用Scrapy),并简要说明我必须使用该工具来获得期望的结果,我将不胜感激。您不必为我写完整的代码。谢谢!

3 个答案:

答案 0 :(得分:1)

This answer似乎为您提供了一个“剪切”准备就绪的答案。 (如果您的HTML请求大约需要5秒钟,您也可能会增加线程池的大小。)对于您的确切问题,代码:

def crawlToCSV(URLrecord):
    OpenSomeSiteURL = urllib2.urlopen(URLrecord)
    Soup_SomeSite = BeautifulSoup(OpenSomeSiteURL, "lxml")
    OpenSomeSiteURL.close()

    return Soup_SomeSite.title.string

将在results中创建标题列表。

答案 1 :(得分:1)

由Santhosh Hari进行的this article on medium快速搜索“ python中的异步抓取”。请阅读本文,因为他对代码的工作原理进行了解释。

使用asyncio和aiohttp库的帖子内容如下。

import asyncio
import aiohttp
import requests

async def fetch_url(session, url):
    async with session.get(url, timeout=60 * 60) as response:
        return await response.text()

async def fetch_all_urls(session, urls, loop):
    results = await asyncio.gather(*[fetch_url(session, url) for url in urls],
    return_exceptions=True)
    return results

def get_htmls(urls):
    if len(urls) > 1:
        loop = asyncio.get_event_loop()
        connector = aiohttp.TCPConnector(limit=100)
        with aiohttp.ClientSession(loop=loop, connector=connector) as session:
            htmls = loop.run_until_complete(fetch_all_urls(session, urls, loop))
        raw_result = dict(zip(urls, htmls))
    else:
        headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'}
        raw_result = requests.get(urls[0], headers=headers).text

    return raw_result

result_dict = get_htmls(url_list)

答案 2 :(得分:1)

我可以建议的一个想法是在Csv中获取所有网址,并根据需要保留一些标题,例如path,title div,body div,image div,并继续添加特定的div(div class =“ title” )。

例如:        路径标题DIV图像DIV身体DIV

类似地,您可以在一个csv文件中提供所有链接,并通过python脚本读取它,以便提取所有数据。