Python7個爬蟲小案例詳解(附源碼)上篇

本次的7個python爬蟲小案例涉及到瞭re正則、xpath、beautiful soup、selenium等知識點,非常適合剛入門python爬蟲的小夥伴參考學習。

前言

關於Python7個爬蟲小案例的文章分為三篇,本篇為上篇,共兩題,其餘兩篇內容請關註!

題目一:

使用正則表達式和文件操作爬取並保存“百度貼吧”某帖子全部內容(該帖不少於5頁)

 本次選取的是百度貼吧中的NBA吧中的一篇帖子,帖子標題是“克萊和哈登,誰歷史地位更高”。爬取的目標是帖子裡面的回復內容。

源程序和關鍵結果截圖:

import csv
import requests
import re
import time
 
def main(page):
    url = f'https://tieba.baidu.com/p/7882177660?pn={page}'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36'
    }
    resp = requests.get(url,headers=headers)
    html = resp.text
    # 評論內容
    comments = re.findall('style="display:;">                    (.*?)</div>',html)
    # 評論用戶
    users = re.findall('class="p_author_name j_user_card" href=".*?" rel="external nofollow"  target="_blank">(.*?)</a>',html)
    # 評論時間
    comment_times = re.findall('樓</span><span class="tail-info">(.*?)</span><div',html)
    for u,c,t in zip(users,comments,comment_times):
        # 篩選數據,過濾掉異常數據
        if 'img' in c or 'div' in c or len(u)>50:
            continue
        csvwriter.writerow((u,t,c))
        print(u,t,c)
    print(f'第{page}頁爬取完畢')
 
if __name__ == '__main__':
    with open('01.csv','a',encoding='utf-8')as f:
        csvwriter = csv.writer(f)
        csvwriter.writerow(('評論用戶','評論時間','評論內容'))
        for page in range(1,8):  # 爬取前7頁的內容
            main(page)
            time.sleep(2)

題目二:

實現多線程爬蟲爬取某小說部分章節內容並以數據庫存儲(不少於10個章節) 

 本次選取的小說網址是全本小說網https://www.qb5.tw/,這裡我們選取第一篇小說進行爬取

然後通過分析網頁源代碼分析每章小說的鏈接

找到鏈接的位置後,我們使用Xpath來進行鏈接和每一章標題的提取

在這裡,因為涉及到多次使用requests發送請求,所以這裡我們把它封裝成一個函數,便於後面的使用

每一章的鏈接獲取後,我們開始進入小說章節內容頁面進行分析

通過網頁分析,小說內容都在網頁源代碼中,屬於靜態數據

這裡我們選用re正則表達式進行數據提取,並對最後的結果進行清洗

然後我們需要將數據保存到數據庫中,這裡我將爬取的數據存儲到mysql數據庫中,先封住一下數據庫的操作

接著將爬取到是數據進行保存

最後一步就是使用多線程來提高爬蟲效率,這裡我們創建瞭5個線程的線程池

 源代碼及結果截圖:

import requests
from lxml import etree
import re
import pymysql
from time import sleep
from concurrent.futures import ThreadPoolExecutor
 
def get_conn():
    # 創建連接
    conn = pymysql.connect(host="127.0.0.1",
                           user="root",
                           password="root",
                           db="novels",
                           charset="utf8")
    # 創建遊標
    cursor = conn.cursor()
    return conn, cursor
 
def close_conn(conn, cursor):
    cursor.close()
    conn.close()
 
def get_xpath_resp(url):
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36'}
    resp = requests.get(url, headers=headers)
    tree = etree.HTML(resp.text)  # 用etree解析html
    return tree,resp
 
def get_chapters(url):
    tree,_ = get_xpath_resp(url)
    # 獲取小說名字
    novel_name = tree.xpath('//*[@id="info"]/h1/text()')[0]
    # 獲取小說數據節點
    dds = tree.xpath('/html/body/div[4]/dl/dd')
    title_list = []
    link_list = []
    for d in dds[:15]:
        title = d.xpath('./a/text()')[0]  # 章節標題
        title_list.append(title)
        link = d.xpath('./a/@href')[0]   # 章節鏈接
        chapter_url = url +link  # 構造完整鏈接
        link_list.append(chapter_url)
    return title_list,link_list,novel_name
 
def get_content(novel_name,title,url):
    try:
        cursor = None
        conn = None
        conn, cursor = get_conn()
        # 插入數據的sql
        sql = 'INSERT INTO novel(novel_name,chapter_name,content) VALUES(%s,%s,%s)'
        tree,resp = get_xpath_resp(url)
        # 獲取內容
        content = re.findall('<div id="content">(.*?)</div>',resp.text)[0]
        # 對內容進行清洗
        content = content.replace('<br />','\n').replace('&nbsp;',' ').replace('全本小說網 www.qb5.tw,最快更新<a href="https://www.qb5.tw/book_116659/" rel="external nofollow" >宇宙職業選手</a>最新章節!<br><br>','')
        print(title,content)
        cursor.execute(sql,[novel_name,title,content])  # 插入數據
        conn.commit()  # 提交事務保存數據
    except:
        pass
    finally:
        sleep(2)
        close_conn(conn, cursor)  # 關閉數據庫
 
 
if __name__ == '__main__':
    # 獲取小說名字,標題鏈接,章節名稱
    title_list, link_list, novel_name = get_chapters('https://www.qb5.tw/book_116659/')
    with ThreadPoolExecutor(5) as t:  # 創建5個線程
        for title,link in zip(title_list,link_list):
            t.submit(get_content, novel_name,title,link)  # 啟動線程

到此這篇關於Python7個爬蟲小案例詳解(附源碼)上篇的文章就介紹到這瞭,其他兩個部分的內容(中、下篇)請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: