新手福利, 正经爬虫教学, 手把手抓取壳蛋网所有文章!

简介

首先看下我们的小白鼠站点: 壳蛋网,这是一个博客,主要是发布个人文章或者收录网上优质文章, 包含SEO丶网赚丶编程技术等内容。
新手福利, 正经爬虫教学, 手把手抓取壳蛋网所有文章!_第1张图片
接下来就通过实践一步一步的将整站文章抓取下来。

页面分析

观察这张图片:
新手福利, 正经爬虫教学, 手把手抓取壳蛋网所有文章!_第2张图片
可以发现其实导航栏就是一个分类来的, 所以我们要做的就算将右侧分类目录下的分类先抓取下来。

新手福利, 正经爬虫教学, 手把手抓取壳蛋网所有文章!_第3张图片
查看该图可以发现,分类是包含在一个class="widget_categories"的标签里面的。

新手福利, 正经爬虫教学, 手把手抓取壳蛋网所有文章!_第4张图片
里面的li标签对应的a标签链接,就是分类目录了,先将这些分类链接抓取下来。

随便点击一个文章多一点的分类:
新手福利, 正经爬虫教学, 手把手抓取壳蛋网所有文章!_第5张图片
可以看到尾页的页码和链接包裹在

', html) if len(search_page) == 0: # 搜索不到表明只有1页 max_page = 1 else: max_page = int(search_page[0]) for page in range(1, max_page + 1): cate_page_url = url + '/page/' + str(page) # 分页页码拼接 cate_html = fetch_html(cate_page_url) soup = BeautifulSoup(cate_html, 'html.parser') article_div = soup.find_all('article', {'class': 'excerpt'}) # 查找文章标签 for art in article_div: art_url = art.h2.a.attrs['href'] # 文章链接 art_title = art.h2.a.text # 文章标题 articles.append({ 'title': art_title, 'url': art_url }) print('正在获取分类:{} 下的文章列表完成, 共{}篇...'.format(title, len(articles))) return articles

爬取文章详情

def save_article(q):
    """
    :return:
    """
    while not q.empty():
        data = q.get()
        save_dir = os.path.join(os.getcwd(), data['cate_name'])
        if not os.path.exists(save_dir):
            os.makedirs(save_dir)
        title = data['title']
        save_path = os.path.join(save_dir, title + '.html')
        save_path.replace('/', r'\/')  # 将/转义
        print('正在获取文章: 《{}》内容...'.format(title))
        url = data['url']
        text = fetch_html(url)
        soup = BeautifulSoup(text, 'html.parser')
        # 将文章体保存, 文章标题跟之前拿到的是一样的,无需再提取
        article_content = soup.find('article', {'class': 'article-content'}) 
        with open(save_path, 'w') as f:
            f.write(str(article_content))

完整代码

# _*_coding:utf8_*_
# Project: kdw_spider
# File: main.py
# Author: ClassmateLin
# Email: [email protected]
# Time: 2020/3/30 4:55 下午
# DESC:
import requests
from bs4 import BeautifulSoup
import re
import os
import queue


def fetch_html(url):
    """
    获取网页html源码
    :return:
    """
    try:
        response = requests.get(url)
        return response.text
    except Exception as e:
        print(e.args)
        return None


def get_category(url='https://www.fenlanli.com/'):
    """
    :return:
    """
    res = []
    html = fetch_html(url)
    soup = BeautifulSoup(html, 'html.parser')
    category_div = soup.find('div', {'class': 'widget_categories'})
    a_tag_list = category_div.find_all('a')  # 查找分类块下所有的分类a标签
    for a_tag in a_tag_list:
        res.append({
            'title': a_tag.text,  # 取分类名称
            'url': a_tag.attrs['href']  # 取分类链接
        })
    return res


def get_article_list(category: dict):
    """
    获取文章链接
    :return:
    """
    articles = []
    url = category['url']
    title = category['title']
    print('正在获取分类:{} 下的文章列表...'.format(title))
    html = fetch_html(url)
    # 正则表达式搜索尾页页码
    search_page = re.findall('尾页
  • 共 (.*?) 页
  • ', html) if len(search_page) == 0: # 搜索不到表明只有1页 max_page = 1 else: max_page = int(search_page[0]) for page in range(1, max_page + 1): cate_page_url = url + '/page/' + str(page) # 分页页码拼接 cate_html = fetch_html(cate_page_url) soup = BeautifulSoup(cate_html, 'html.parser') article_div = soup.find_all('article', {'class': 'excerpt'}) # 查找文章标签 for art in article_div: art_url = art.h2.a.attrs['href'] # 文章链接 art_title = art.h2.a.text # 文章标题 articles.append({ 'title': art_title, 'url': art_url }) print('正在获取分类:{} 下的文章列表完成, 共{}篇...'.format(title, len(articles))) return articles def save_article(q): """ :return: """ while not q.empty(): data = q.get() save_dir = os.path.join(os.getcwd(), data['cate_name']) if not os.path.exists(save_dir): os.makedirs(save_dir) title = data['title'] save_path = os.path.join(save_dir, title + '.html') save_path.replace('/', r'\/') # 将/转义 print('正在获取文章: 《{}》内容...'.format(title)) url = data['url'] text = fetch_html(url) soup = BeautifulSoup(text, 'html.parser') # 将文章体保存, 文章标题跟之前拿到的是一样的,无需再提取 article_content = soup.find('article', {'class': 'article-content'}) with open(save_path, 'w') as f: f.write(str(article_content)) if __name__ == '__main__': q = queue.Queue() categories = get_category() for cate in categories: articles = get_article_list(cate) for art in articles: art['cate_name'] = cate['title'] q.put(art) save_article(q)

    你可能感兴趣的:(Python)