爬虫:爬取新闻内容及图片,存入数据库

目录

一、需求

二、代码


一、需求

1、对新闻主页上的新闻进行爬取,要求解析出标题、内容、新闻类型、图片并存入数据库。

2、只爬取带有图片的新闻,一张即可。

二、代码

以下是对新华网爬取的代码示例。

python 复制代码
import requests as rq
from bs4 import BeautifulSoup
import re,os
import datetime
from datetime import timedelta
from difflib import SequenceMatcher
from gbase import GBASE_DB 
from conf import IMGPATH,LOCALPATH,PICSIZE

xinhua_dict = {'politics':1, #时政
               'culture':2, #文化
               'health':3,  #健康
               'fortune':4,  #财经
               'world':5,  #国际
               }
    
def classify_news(s, news_list):
    for li in news_list:
        if li in s:
            return li
    return None
    
def get_xinhua_news(url):
    '''
    爬取新华网标题、内容、分类、图片
    '''
    newsWeb = rq.get(url)
    newsWeb.encoding = 'utf-8'
    soup = BeautifulSoup(newsWeb.text,'html.parser')
    #获取标题
    title_element = soup.find('span', class_='title')
    title = title_element.get_text(strip=True)
    #获取分类
    news_type = xinhua_dict[classify_news(url,xinhua_dict.keys())]
    #获取内容
    content_element = soup.find('div', id='detail')
    paragraphs = content_element.find_all('p')
    content = '\n'.join(paragraph.get_text(strip=True) for paragraph in paragraphs)
    content = re.sub('\n+', '\n', content).replace('"', '\\"').replace('\n', '\\n')
    #获取图片
    jpg_element = soup.find_all('img')
    jpg_pattern = re.compile(r'src="([^"]*1n\.(jpg|jpeg))"')
    j_list = jpg_pattern.findall(str(jpg_element))
    for j in j_list:
        jpg_path = os.path.basename(j[0])
        jpg_url = url[:url.find('c_')] + jpg_path
        picture = rq.get(jpg_url)
        if picture.status_code==200:
            if len(picture.content)>PICSIZE:
                with open(LOCALPATH+jpg_path,"wb") as f:
                    f.write(picture.content)
                return_path = IMGPATH+jpg_path
                break
        else:
            pass
    return title,news_type,content,return_path

def main():
    db = GBASE_DB()
    newsUrl = 'http://www.xinhuanet.com/'
    newsWeb = rq.get(newsUrl)
    newsWeb.encoding = 'utf-8'
    soup = BeautifulSoup(newsWeb.text,'lxml')
    #获取新闻网址列表
    link_list = []
    li_elements = soup.find_all('li')
    for li_element in li_elements:
        a_element = li_element.find('a')
        if a_element:
            url = a_element.get('href')
            if url.startswith("http://www.news.cn/") and url.endswith(".htm") and 'c_' in url and classify_news(url,xinhua_dict.keys())!=None:
                link_list.append(url)

    #逐个解析新闻网址
    for link in link_list:
        try:
            title,news_type,content,jpg_path = get_xinhua_news(link)

            sql = '''insert into table_name(title,type,content,image) 
                     values ('{}', {},'{}','{}')
                  '''.format(title,news_type,content,jpg_path)
            db.execute_sql(sql)
            print('(成功)爬取新华网:',title)
        except Exception as e:
            print('爬取失败:',link,' :',e)
            continue
            
if __name__ == '__main__':
    main()

首先,对新华网主页进行爬取,获取页面上所有的新闻链接,存放进入link_list列表中。

然后,依次访问每一个新闻链接,并解析标题、内容,需要对空格、特殊字符等做一下清洗。根据子频道路径进行分类,并爬取像素值大于阈值的图片(避免爬取到页面上的二维码等小图),图片保存在服务器本地某个文件夹下,如果没有符合条件的图片,则会报错,在main函数中抛出异常,跳过此新闻链接的爬取。

最后,存入数据库。

相关推荐
银发控、1 小时前
MySQL联合索引
数据库·mysql
予枫的编程笔记1 小时前
【MySQL修炼篇】从踩坑到精通:事务隔离级别的3大异常(脏读/幻读/不可重复读)解决方案
数据库·mysql·后端开发·数据库事务·事务隔离级别·rr级别·脏读幻读不可重复读
rayufo2 小时前
【工具】列出指定文件夹下所有的目录和文件
开发语言·前端·python
一起养小猫3 小时前
Flutter for OpenHarmony 实战:记账应用数据统计与可视化
开发语言·jvm·数据库·flutter·信息可视化·harmonyos
世界尽头与你3 小时前
(修复方案)CVE-2023-22047: Oracle PeopleSoft Enterprise PeopleTools 未授权访问漏洞
数据库·安全·oracle·渗透测试
韩立学长3 小时前
【开题答辩实录分享】以《智能大学宿舍管理系统的设计与实现》为例进行选题答辩实录分享
数据库·spring boot·后端
Python 老手3 小时前
Python while 循环 极简核心讲解
java·python·算法
Henry Zhu1233 小时前
数据库(五):反规范化
数据库
Mr_Xuhhh3 小时前
MySQL函数详解:日期、字符串、数学及其他常用函数
java·数据库·sql
开源技术4 小时前
如何将本地LLM模型与Ollama和Python集成
开发语言·python