爬虫爬取新闻实战01:小白如何迅速学会爬虫爬取千条新闻

1.前言

​ 写这篇博客的原因是作者参加软件杯新闻识别项目,由于题目组提供的数据数量问题而导致需要个人大量采集数据,从而导致被逼无奈去学了爬虫(5555),算是对个人学爬虫的总结,使用了一点特殊的工具,爬虫大佬看着乐呵,比较适合想要快速使用爬虫而学习时间没有那么多的小白(python语言的一个特性就是代码精简,功能强大,可以让小白快速实现一些有趣的功能😘,虽然如果是为了长期使用,我不是很推荐这样偷工减料😂)。

2 .爬虫原理介绍

在博主接触过的两种爬虫中,

2.1.图片爬虫

其中最为简单也最能复用的爬虫是,利用程序模拟浏览器关键词搜索图片然后直接爬取百度图库或谷歌图库里的图片,例如这份代码,(可以直接使用修改一下关键词和图片存储地址就行了,也是从网上找的)

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options

from urllib import error
from urllib import request
import os
import time
import sys

# default url 
# replace for yours
url = "https://www.google.com"
explorer = "Chrome"#使用谷歌浏览器
# 存储文件地址
imgs_dir = "images"
#搜索关键词
search_words="珈乐Carol"


# report hook with three parameters passed
# count_of_blocks  The number of blocks transferred
# block_size The size of block
# total_size Total size of the file
def progress_callback(count_of_blocks, block_size, total_size):
    # determine current progress
    progress = int(50 * (count_of_blocks * block_size) / total_size)
    if progress > 50:
        progress = 50
    # update progress bar
    sys.stdout.write("\r[%s%s] %d%%" % ('█' * progress, '  ' * (50 - progress), progress * 2))
    sys.stdout.flush()


class CrawlSelenium:

    def __init__(self, explorer="Chrome", url="https://www.google.com"):
        self.url = url
        self.explorer = explorer

    def set_loading_strategy(self, strategy="normal"):
        self.options = Options()
        self.options.page_load_strategy = strategy


    def crawl(self):
        # instantiate driver according to corresponding explorer
        if self.explorer == "Chrome":
            self.driver = webdriver.Chrome(options=self.options)
        if self.explorer == "Opera":
            self.driver = webdriver.Opera(options=self.options)
        if self.explorer == "Firefox":
            self.driver = webdriver.Firefox(options=self.options)
        if self.explorer == "Edge":
            self.driver = webdriver.Edge(options=self.options)

        # search on google
        # navigate to url
        self.driver.get(self.url)
        # locate input field
        search_input = self.driver.find_element(By.NAME, 'q')
        # emulate user input and enter to search
        webdriver.ActionChains(self.driver).move_to_element(search_input).send_keys(search_words + Keys.ENTER).perform()
        

        # navigate to google image
        # find navigation buttons
        self.driver.find_element(By.LINK_TEXT, '图片').click()

        # load more images as many as possible
        # scrolling to bottom
        self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
        # get button
        show_more_button = self.driver.find_element(By.CSS_SELECTOR, "input[value='显示更多搜索结果']")
        try:
            while True:
                # do according to message
                message = self.driver.find_element(By.CSS_SELECTOR, 'div.OuJzKb.Bqq24e').get_attribute('textContent')
                # print(message)
                if message == '正在加载更多内容,请稍候':
                    self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
                elif message == '新内容已成功加载。向下滚动即可查看更多内容。':
                    # scrolling to bottom
                    self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
                    if show_more_button.is_displayed():
                        show_more_button.click()
                elif message == '看来您已经看完了所有内容':
                    break
                elif message == '无法加载更多内容,点击即可重试。':
                    show_more_button.click()
                else:
                    self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
        except Exception as err:
            print(err)

        # find all image elements in google image result page
        imgs = self.driver.find_elements(By.CSS_SELECTOR, "img.rg_i.Q4LuWd")
        
        img_count = 0
        for img in imgs:
            try:
                # image per second
                time.sleep(1)
                print('\ndownloading image ' + str(img_count) + ': ')
                img_url = img.get_attribute("src")
                if img_url == None:
                    continue
                path = os.path.join(imgs_dir, str(img_count) + "_img.jpg")
                request.urlretrieve(url = img_url, filename = path, reporthook = progress_callback, data = None)
                img_count = img_count + 1
            except error.HTTPError as http_err:
                print(http_err)
            except Exception as err:
                print(err)



def main():
    # setting
    crawl_s = CrawlSelenium(explorer, url)
    crawl_s.set_loading_strategy("normal")
    # make directory
    if not os.path.exists(imgs_dir):
        os.mkdir(imgs_dir)
    # crawling
    crawl_s.crawl()


if __name__ == "__main__":
    main()

运行该程序谷歌浏览器会自动启动搜索珈乐Carol并下载有关的图片到我们指定的文件夹,结果如下

在这里插入图片描述

2.2 文字爬虫

文字爬虫的意思是从网页获取相关文字内容,他的本质其实是根据网页结构来爬取网页的相关内容,所以如果是爬取不同的网站其实程序是需要根据不同的网页结构来改编程序的(所以如果你在网上看到一些爬虫想直接复用用不了,建议先看一下日期,不是程序错了,可能是爬取的对应网站结构变了😉)

那么先解释一下是怎么通过网页结构爬虫的首先我们先看一篇简单的新闻网页 我国新能源汽车数量约占全球总量一半-新华网 (xinhuanet.com)

在这里插入图片描述

对于这样的一篇普通的新闻网页,假设我们要做的就是爬取该新闻的内容,我们该如何使用呢?对于这样的问题,我们先用三行代码😋获取他的页面源代码:

from bs4 import BeautifulSoup
import requests
res = requests.get('http://www.xinhuanet.com/fortune/2021-06/18/c_1127577431.htm')#新闻的网址
res.encoding = res.apparent_encoding  
# 根据网站的编码方式修改解码方式,因为网页的文字编码方式多种多样有UTF-8 GBK这些解码方式如果不一致容易发生乱码,所以解码方式最好不要统一,而是交给网页自己来决定
soup = BeautifulSoup(res.text, 'html5lib')#使用html5lib样式来解析网页,看不懂没关系
print(soup)#查看页面源代码

在这里插入图片描述

那么可以看到我们获得的代码是不是特别的眼熟,这不就是HTML语言,也就是通过这几行代码,我们获取到了网页的源代码,那么我们的目标是要获得新闻的正文也自然可以。观察页面结构(经过我搜集资料,爬虫是一个你有时必须观察页面结构的活,不能省)我们的新闻正文全部在上图被

标签包裹着,那么是不是代码我们只要从源代码中爬取该

然后提取所有文字不就行了吗✔?说干就干:

data = soup.select('p')#元素选择器
news_text=''
for p in data:
    news_text += p.text.strip()
print(news_text)

输出新闻如下:

在这里插入图片描述

可以看到我们只用了这么几段短短的代码就读取到了,整个新闻的内容,那么说明我们爬虫只需要一个新闻链接就能爬取了到对应的链接了,但是我们忽视了一个问题,那就是我们从哪里获取这么多的新闻链接,还是只能爬虫来爬取,但是由于实在是不好爬取(我技术菜也是事实😢),所以这里我们需要借用一个软件。

3.用八爪鱼爬取新闻链接

八爪鱼(八爪鱼采集器 - 免费网络爬虫软件_网页大数据抓取工具 (bazhuayu.com))是一个可以自动爬取网页相关内容的软件,真不是打广告(别人也瞧不起我这点流量🤣),只是他实在是太方便好用了,同时的他的免费版对于非企业人士的需求我感觉也够用了,八爪鱼可以根据给定的网页来爬取对应内容,但由于我这边的需求爬取新闻是有特定要求的,所以我这里爬取的必须是特定频道的,例如访问新华网财经频道

在这里插入图片描述

八爪鱼会自动爬取该页面的文字以及相关链接,同时提供给我们多种选择方案和自定义的对于采集数据的限制,例如在这里我选择的方案是抓取标题和链接,生成采集设置后直接开始自动采集

在这里插入图片描述

同时为了方便保存我们还可以直接将爬取的数据存入多种样式的文件进行保存
在这里插入图片描述

这里我选择将数据保存成EXCEL文件,打开该EXCEL文件,我们可以看到我们采集的数据

在这里插入图片描述

当然有时候一个网站可能并没有采集那么多数据,我们可以多访问几个网站,多收集点数据(偶尔遇到一些会采集几千条数据的要注意别让某种特别的新闻太多了扰乱数据后期也不好清理),比如我个人的习惯是将同一种类的所有数据放一起,然后最后运行代码合并
在这里插入图片描述

#合并所有数据
import pandas as pd
import glob
all_excel_path=glob.glob('军事/*.xlsx')
df_all=pd.DataFrame()
for excel_path in all_excel_path:
	data=pd.read_excel(excel_path)
	df_all=df_all.append(data)
df_all.to_excel('军事/军事总和.xlsx')

可以看到最后我们合并所有数据制作了一个存储将近一千条数据的表格

在这里插入图片描述

而在第二节那里,我们说过只需要该新闻的链接我就能获取到该新闻的正文,所以我们接下来只需要访问这些所有链接,就能获得大量的新闻:

import requests
from bs4 import BeautifulSoup
import pandas as pd
dataf = pd.read_excel('科技.xlsx')
title = dataf['标题']
channelName = []
net = dataf['标题_链接']
content = []
print(dataf.head())
num = 0
for link_href in net:
    try:
        news_text = ''
        res = requests.get(link_href)
        res.encoding = res.apparent_encoding  # 根据网站的编码方式修改解码方式
        soup = BeautifulSoup(res.text, 'html5lib')
        data = soup.select('p')
        for p in data:
            news_text += p.text.strip()
        content.append(news_text)
        channelName.append('科技')
        num += 1
        print(num)
    except:
        pas
title = title[:len(content)]
#使用dataframe来进行存储
total_data = {'content': content, 'channelName': channelName, 'title': title}
data = pd.DataFrame(total_data)
#保存成EXCEL格式
data.to_excel('爬取总和数据/科技.xlsx')

运行成功后可以看到该段程序保存出了一个文件每条新闻分别有content正文,channelName频道,title标题的三大属性(由于我训练数据需要,所以必须得知每个新闻的所属分类)

在这里插入图片描述

那么至此我们的爬取数据新闻任务就成功了😉。

4.结语

在本例中,我介绍了一种较为简洁(代码总共都没几行🤗)同时也较为容易被小白(我个人也是一个才接触爬虫没几天的人🧐)所接受的爬取新闻的方法,但可以预见的是该种代码的缺点也是不可忽视的,无法自动的采集大量数据,需要我们提前利用八爪鱼爬取大量新闻链接,如有更好的意见欢迎评论区指教🥰。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐