分享一个零基础快速爬取数据的工具

今天介绍下如何使用pyppeteer抓取网页的数据。pyppeteer是web应用自动化测试的具,可以直接运行在浏览器中,通过代码控制与页面上元素进行交互,并获取对应的信息。

以前我们我们爬取数据都是通过写代码爬取,当待爬取的网站需要登录时,我们需要在代码中模拟登录;当爬取过快需要验证时,我们需要在代码中实现验证逻辑;当ip被封时,还需要有自己的动态ip库。待爬网站的反爬策略越多,我们爬取的成本就越大。总之,用写代码的方式爬取数据需要构造比较复杂的请求,想尽一切办法将爬虫伪装成真实的用户。

使用pyppeteer这样的工具,就可以在很大程度上解决上面的问题。同时,还有一个优点是所见即所得,不需要再去研究网页复杂的请求结构。当然这类工具也是优缺点的,它增加了你去理解网页上各种元素以及交互的成本。所以我觉得这类工具最适合在短平快的爬虫场景中使用。比如我在最近的工作中就遇到两次这样的情况,想爬一些特别简单的数据来提升工作效率,但又不想研究网页是如何构造请求的,用这种所见即所得的工具就可以快速抓取想要的数据。

下面我们以“抓取百度搜索数据”例子我介绍一下pyppeteer的使用。正式介绍前我们先来看下爬取效果:

安装pyppeteer

python3 -m pip install pyppeteer

安装完成后,执行pyppeteer-install命令安装最新版本的 Chromium 浏览器。根据官方文档的说明,安装pyppeteer需要Python3.6以上的版本。

由于pyppeteer是基于asyncio实现的,所以我们的代码中也会用async/await来写代码,之前没写过的朋友也不用担心,基本不影响对pyppeteer的使用,有必要的话以后再单独写篇文章介绍。

首先,用pyppeteer启动 chrome 进程

from pyppeteer import launch
# headless 显示浏览器
# --window-size 设置窗体大小
browser = await launch({'headless': False,
                        'args': ['--window-size=%d,%d' % (width, height)]
                        })

然后,打开一个新的标签,并访问百度

# 打开新页面
page = await browser.newPage()  
# 设置内容显示大小
await page.setViewport({"width": width, "height": height})  
# 访问百度
await page.goto('https://www.baidu.com')  

打开百度网站后,下一步就要向搜索输入框输入内容,首先要找到输入框的html标签 分享一个零基础快速爬取数据的工具_第1张图片 从上图可以看到,代码代表搜索输入框,该标签的 class 是s_ipt,那下面我们就通过type函数找到该标签,并键入需要搜索的内容

# 将对应的 selector 填入 python,通过.s_ipt找到输入框html标签
await page.type('.s_ipt', 'python')

这里我们搜的是python,有了输入后就可以点击“百度一下”按钮来发起搜索。找按钮的方式与上面一样 可以看到代码代表“百度一下”的按钮,该标签的 id 是su,下面就调用click函数找到该标签,并点击

# 通过#su找到“百度一下”按钮html标签
await page.click('#su')

这里需要注意su前面是#而不是.,因为在html标签中它用id表示而不是class,这里涉及html selector的内容,不清楚的朋友可以简单补一下。

执行完上面的代码,我们可以看到搜索结果了,调用screenshot方法将当前页面保存

await page.screenshot({'path': 'example.png'})

效果如下: 分享一个零基础快速爬取数据的工具_第2张图片 接下来我们就获取网页内容,并解析每条结果

# 获取网页内容
content = await page.content()
# 解析
output_search_result(content)

通过BeatifulSoup解析每条结果的标题与链接

def output_search_result(html):
    search_bs = BeautifulSoup(html, 'lxml')

    all_result = search_bs.find_all("div", {'class': "result c-container"})
    for single_res in all_result:
        title_bs = single_res.find("a")
        title_url = title_bs.get('href')
        title_txt = title_bs.get_text()

        print(title_txt, title_url)

输出的内容如下

python官方网站 - Welcome to Python.org http://www.baidu.com/link?url=OqtoElo8HW1GdOgAlqdCTz2lpewFLf0HlbnGdyAKD06BfPbw0fsJ_N5fclxx-q1D
Python 基础教程 | 菜鸟教程 http://www.baidu.com/link?url=IooFgJjdec1qPXhGhF7tur-z2Qt_43RkK3L-9cp8oB-0i2w7unKzLayLjg3zSQeKQieA49JFejMjqTM-TSY3V_
Python3 * 和 ** 运算符_python_极客点儿-CSDN博客 http://www.baidu.com/link?url=H3VdAQRAbTkN9jGJGkvhIFTdg48O-b5yib7vCquWyg1-6FZwBVHnJ5iiUYQkjbf-8IuLfOwDXoUMDOdMvXNHkzejts4uRHrczgQqekgQuFy
Python教程 - 廖雪峰的官方网站 http://www.baidu.com/link?url=piu0nEfXNvkLhWchcdX2EjJvIkQ5beq2_uYH_B7u2vjYO82BZwr8SXgDxnVLZYgGL8xuR_ovjg2cAYfPS9AmLtqUQP-TrWuJWHNqYbxdQnUPTy_VPp8sSBdCaYBl9YDX
Python3 教程 | 菜鸟教程 http://www.baidu.com/link?url=bx1rMrzxC69Sp0zY08-VhFs40QQ8UFxZdvmZVFcKYkCG2mdojhAMjk5ulKBKwQm77x8vMyOeowW_bNtoP35m3q
你都用 Python 来做什么? - 知乎 http://www.baidu.com/link?url=YTMr1ycFjtkWx8lgJ_PT3-kF50vYI6Yibh4o69WL_afBSOkkZmGxexxIKXY3fGAX8X2-AaFbI4jL1vJbKMJrsK
Python基础教程,Python入门教程(非常详细) http://www.baidu.com/link?url=elAepKY7rhULzTPuwKvk8Cxx21K5D0Ey7-Wj9TZgN49MyasPOXtLYfWbp46QZQie

这样,我们的抓取数据的目的已经达到了,当然我们还可以继续拓展下,多用用pyppeteer,比如:我们可以点击下一页,抓取下一页的内容

# next page
# 为了点击“下一页”,需要将当前页面滑到底部
dimensions = await page.evaluate('window.scrollTo(0, window.innerHeight)')
# 点击“下一页”按钮
await page.click('.n')
# 获取第二页的内容
content = await page.content()
# 解析
output_search_result(content)

操作与之前类似,注释写的也比较清楚,我就不再赘述了。最后可以调用await browser.close()代码关闭浏览器。上述代码可以定义需要定义在一个async函数中,如:

async def main():
  # ... 抓取代码

然后通过下面代码

asyncio.get_event_loop().run_until_complete(main())

调用main函数。

pyppeteer的用法就介绍到这里了,类似的工具还有很多,比如:Selenium,我也试了下,确实如网上所说配置上面需要花些功夫,有兴趣的朋友可以自行尝试。希望今天的内容对你有用。关注公众号回复关键字 爬虫 获取完整源码

欢迎公众号「渡码」,输出别地儿看不到的干货。

你可能感兴趣的:(分享一个零基础快速爬取数据的工具)