第二次作業-python爬取網頁及數據分析與展示


這個作業屬於哪個課程 https://edu.cnblogs.com/campus/fzzcxy/ZhichengSoftengineeringPracticeFclass/
這個作業要求在哪里 https://edu.cnblogs.com/campus/fzzcxy/ZhichengSoftengineeringPracticeFclass/homework/12532
這個作業的目標 培養良好的編碼習慣及博客記錄,提升自學能力
Gitee 地址 https://gitee.com/yu-huangqiang/get-data

朴朴商城價格監控

解題思路描述

  • 說實話拿到這個課題還是挺興奮的,爬蟲是當下非常火的一項技術,作為計算機專業學生不會爬蟲都說不過去,早就想爬取一些東西了。剛好借用這個機會實現一下。
  • 查找資料后大致理解了爬蟲的基本原理,以及fiddler的原理及使用。fiddler抓包工具,可以理解為是一個代理,是用戶到服務器的一個中間層,通過它可以監控到用戶-服務器的請求。由於爬取的朴朴商城是移動端的數據,在pc端是不能直接訪問移動端的接口的。所以我們要借助fiddler工具對移動端接口進行抓取接口。

設計實現過程

  • 第一步:首先安裝fiddler軟件,(我使用的是mac端的,注冊賬號后就可以使用,如果是windows版的需要修改配置后才能抓取到同一局域網上的設備請求)
  • 第二步: 修改配置:將手機和電腦連在同一wifi上,修改手機wifi配置:添加代理,將代理地址和端口修改fiddler的地址和端口,這一步是讓手機發送的請求通過fidller層,fiddler在后台就可以監控到手機發送的所有請求。最后在手機瀏覽器訪問剛剛添加的代理地址和端口,然后下載證書。(手機廠商為了保護用戶安全默認情況下是不允許通過第三方代理來發送請求的,需要安裝信任證書!)
  • 第三步: 抓取app接口:使用手機打開app訪問頁面,在fiddler上尋找接口地址。
  • 第四步: 獲取數據:使用python來模擬手機向服務器發送請求來獲取數據
最終效果

代碼說明

點擊查看代碼
添加請求頭,這里的 user-agent 是設備標識

headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'
}
url = 'https://www.zhihu.com/api/v4/people/fcc808ca04188e8fbfebd590592583ec/collections?include=data%5B*%5D.updated_time%2Canswer_count%2Cfollower_count%2Ccreator%2Cdescription%2Cis_following%2Ccomment_count%2Ccreated_time%3Bdata%5B*%5D.creator.vip_info&offset=0&limit=10'


# 獲取收藏夾的id 和 收藏夾名。想打開收藏夾需要收藏夾的id
favoriteId = []
def getFavoriteId():
    r = requests.get(url,headers=headers).json()
    for i in range(0,len(r['data'])):
        id = r['data'][i]['id']
        title = r['data'][i]['title']
        temp = [
            id,
            title
        ]
        favoriteId.append(temp)
# 根據獲取到的收藏夾的id生成打開收藏夾的鏈接
favoriteLinks = []
def getLink():
    for i in range(0,len(favoriteId)):
        url = 'https://www.zhihu.com/api/v4/collections/'+str(favoriteId[i][0])+'/items?offset=0&limit=20'
        favoriteLinks.append(url)
# 解析收藏夾鏈接里面的內容,提取出內容標題和內容鏈接
def getConent(favoriteLink):
    r = requests.get(favoriteLink,headers=headers).json()
    for i in range(0,len(r['data'])):
        em =r['data'][i]
        result = str(em['content']['question']['title']) + str( em['content']['question']['url'])
        print(result)

if __name__ == '__main__':
    getFavoriteId()
    getLink()
    for i in range(0,len(favoriteLinks)):
        print(favoriteId[i][1]+'************************************************************************************************************************')
        getConent(favoriteLinks[i])

gitee提交:

有關git工具的使用

知乎收藏欄

解題思路描述

  • 有了第一題的鋪墊,對爬蟲技術有了大致的了解上手后,想象爬取知乎數據不是輕車熟路嗎?甚至不需要使用fiddler就可以輕松獲取到接口鏈接(知乎有web版)。可以直接使用谷歌瀏覽器的開發者工具查看網頁的請求頭。但是對於實現過程中還是踩了不少小坑的。讓我們開始吧!

設計實現過程

  • 第一步:輕車熟路,先拿到接口鏈接再說!
  • 第二步:對接口返回的數據進行解析
  • 第三步:整合數據輸出

最終效果

代碼說明

添加請求頭
# 添加請求頭
import requests
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'
}
url = 'https://www.zhihu.com/api/v4/people/fcc808ca04188e8fbfebd590592583ec/collections?include=data%5B*%5D.updated_time%2Canswer_count%2Cfollower_count%2Ccreator%2Cdescription%2Cis_following%2Ccomment_count%2Ccreated_time%3Bdata%5B*%5D.creator.vip_info&offset=0&limit=10'

獲取收藏夾的id 和 收藏夾名。想打開收藏夾需要收藏夾的id
# 根據接口返回的數據,發現每個收藏夾底下有一個id,經過對比后發現這個id是打開收藏夾的鏈接關鍵組成部分,想要打開收藏夾就必須獲取到這個id合成鏈接
favoriteId = []
def getFavoriteId():
    r = requests.get(url,headers=headers).json()
    for i in range(0,len(r['data'])):
        id = r['data'][i]['id']
        title = r['data'][i]['title']
        temp = [
            id,
            title
        ]
        favoriteId.append(temp)
根據獲取到的收藏夾的id生成打開收藏夾的鏈接
# 這個列表是用來放每個收藏夾的鏈接的,傳入剛剛獲取到的id列表,組合成鏈接后存到favoriteLinks列表中
favoriteLinks = []
def getLink():
    for i in range(0,len(favoriteId)):
        url = 'https://www.zhihu.com/api/v4/collections/'+str(favoriteId[i][0])+'/items?offset=0&limit=20'
        favoriteLinks.append(url)
解析收藏夾鏈接里面的內容,提取出內容標題和內容鏈接
# 拿到收藏夾的鏈接后,我們對每個鏈接發送請求,根據返回的內容進行提取輸出
def getConent(favoriteLink):
    r = requests.get(favoriteLink,headers=headers).json()
    for i in range(0,len(r['data'])):
        em =r['data'][i]
        result = str(em['content']['question']['title']) + str( em['content']['question']['url'])
        print(result)

if __name__ == '__main__':
    getFavoriteId()
    getLink()
    for i in range(0,len(favoriteLinks)):
        print(favoriteId[i][1]+'************************************************************************************************************************')
        getConent(favoriteLinks[I])

  • 這里有幾個小坑說一下:第一是收藏夾里的內容接口鏈接分為兩種 。 一種是你收藏了一個相關問題(打開這個鏈接是去到相關問題下)第二種是你收藏了某用戶的原創回答。
    這兩個鏈接返回的數據以及接口形式都不一樣,不能統一處理。一開始我也是納悶了好久,為什么爬到一半就報錯,提示我keyValue值不對,然后我就想是不是返回的數據不同,一看鏈接都不同,果然是這樣!這里需要對返回的鏈接進行判斷屬於哪一種,然后分開提取,統一輸出。

反思

  • 爬取知乎時大部分時間用在了數據篩選上,對正則和python的基本數據格式使用不熟練,很多都是一遍Google一遍寫代碼,我使用的是爬取網站返回的json數據,如果直接爬html里的內容應該會相對輕松些,拿到題目還是要先思考一下怎么做效率更高,等做到一半才發現也只能硬着頭皮接着做。

拉勾網址數據爬取

前言

  • 根據前兩次爬取的經驗,爬蟲無非就是找到網站接口返回的json數據,然后對數據進行清洗嘛!也沒啥新花招。但這次就直接打臉。我在開發中工具找后台返回的json數據時就發現了個問題,壓根找不到!找到的也是一大串看不懂含義的字符。這下咋辦?后來Googe了一下,是后台對數據進行了加密,那咋辦?我還能給它解密?抱歉我本事沒那么大!但是我又想,既然頁面展示的html數據我能看懂,為何不直接爬取html的數據呢?既然如此,給我爬!

設計實現過程

  • 第一步:找到返回html文件的接口。
  • 第二步:使用BeautifulSoup保存格式化后的html數據
  • 第三步:BeautifulSoup配合正則提取數據
  • 第四步:使用xlwt將數據保存到excel表格中

最終效果

代碼說明

添加請求頭
import re
import time
import requests
import urllib3
from bs4 import BeautifulSoup
import xlwt
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# url='https://www.lagou.com/wn/jobs?gj=%E5%9C%A8%E6%A0%A1%2F%E5%BA%94%E5%B1%8A&gm=150-500%E4%BA%BA&kd=%E5%89%8D%E7%AB%AF&fromSearch=true&city=%E7%A6%8F%E5%B7%9E&pn=1'
url = 'https://www.lagou.com/wn/jobs?pn=1&gj=3%E5%B9%B4%E5%8F%8A%E4%BB%A5%E4%B8%8B&gm=150-500%E4%BA%BA&kd=%E5%89%8D%E7%AB%AF&fromSearch=true&city=%E5%B9%BF%E5%B7%9E'
headers = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36',
   }
date = {
        '__lg_stoken__':'d68685c3b049a61aa2b859d085106a80c6f2e695613c2d7e5ae7073c19008bdf69fb5e4a6eece2622e02627ebe2859a5222371409d168a503f115ef6c239a46b2348f92696a3',
        'X_HTTP_TOKEN':' 42daf4b72327b2810802347461bf5e71415983ed09',
        'JSESSIONID':'ABAAAECABFAACEA8440B880856F1D2E85C1AEE70BE1EA44',
        'WEBTJ-ID':'20220316200124-17f929aac8f5f0-0946ee9b10d426-113f645d-3686400-17f929aac90f74',
        'sajssdk_2015_cross_new_user':'1',
        'sensorsdata2015session':'%7B%7D',
        'sensorsdata2015jssdkcross':'%7B%22distinct_id%22%3A%2217f929aafd7cc8-0a64961186fcef-113f645d-3686400-17f929aafd816e7%22%2C%22first_id%22%3A%22%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%2C%22%24os%22%3A%22MacOS%22%2C%22%24browser%22%3A%22Chrome%22%2C%22%24browser_version%22%3A%2299.0.4844.51%22%7D%2C%22%24device_id%22%3A%2217f929aafd7cc8-0a64961186fcef-113f645d-3686400-17f929aafd816e7%22%7D'
}
對接口鏈接進行拼接
urlLists = []
def urlList():
    for i in range(1,7):# 獲取7個
        u = 'https://www.lagou.com/wn/jobs?pn='+str(i)+'&gm=150-500%E4%BA%BA&cl=false&fromSearch=true&labelWords=sug&suginput=%E5%90%8E%E7%AB%AF&kd=%E5%90%8E%E7%AB%AF%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88&city=%E4%B8%8A%E6%B5%B7'
        urlLists.append(u)
def getUrls(urls):
    result=requests.get(urls,cookies=date,headers=headers,verify=False)
    result.encoding='utf-8'
    # f2 = open('date01.html','w',encoding='utf-8')
    # f2.write(result.text)
    htmlDate = result.text
    soup = BeautifulSoup(htmlDate,'lxml')
    return soup
提取數據
# 數據粗清洗,返回一個列表,列表中的數據也是一個列表
def cleaDateFirst(soup):
    li = soup.findAll(class_='item-top__1Z3Zo')
    return li
def clearFinal(soup):
    # 職位
    position = []
    positionTemp = soup.findAll(class_='p-top__1F7CL')
    for i in positionTemp:
        s = re.findall(r'<a>(.*)<!',str(i.a))
        position.append(s)
    # 薪資
    money = []
    money__3Lkgq = soup.findAll(class_='money__3Lkgq')
    for i in money__3Lkgq:
        money.append(i.string)
    # 學歷
    education = []
    pbom__JlNur = soup.findAll(class_='p-bom__JlNur')
    for i in pbom__JlNur:
        e = re.findall(r'</span>(.*)</div>',str(i))
        education.append(e)
    # 公司
    companyname = []
    companyname__2SjF =soup.findAll(class_='company-name__2-SjF')
    for i in companyname__2SjF:
        companyname.append(str(i.a.string))
    return position, money, education, companyname

反思

做這個一開始還是挺懵的,不知道怎么提取html數據,不知道怎么將數據保存到excel,甚至復習了一遍正則。一遍查資料,一遍敲代碼,現學現用,硬是被我拼湊了出來。遇到了不少問題,幸運的是我所生活的這個年代,已經有很多前人寫好了輪子,你只需會用即可!很多坑也有人替你躺過了,你只需避開,不用在一個問題上死磕幾小時,站在前人的肩膀上開發輕松了不少,這里也感謝那些大牛寫的博客,為我提供了寶貴的經驗,作為開發人員寫博客不僅僅能為自己標記踩過的坑,同時也給其它開發中提供了一份寶貴的經驗。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM