1. 程式人生 > 其它 >【資料採集】第二次實驗

【資料採集】第二次實驗

實驗 1

1.1 題目

要求:在中國氣象網(http://www.weather.com.cn)給定城市集的7日天氣預報,並儲存在資料庫。

1.2 思路

1.2.1 傳送請求

  • 匯入包
import urllib.request
  • 構造請求頭併發送請求
    headers={"User-Agent":"Mozilla/5.0 (Windows; U; Windows NT 6.0 x64; en-US; rv:1.9pre) Gecko/2008072421 Minefield/3.0.2pre"}
    req=urllib.request.Request(url,headers=headers)
    data=urllib.request.urlopen(req)

1.2.2 解析網頁

  • 匯入庫(使用BeautifulSoup進行頁面解析)
from bs4 import BeautifulSoup
from bs4 import UnicodeDammit

注意: 這裡還有一個編碼的轉換,防止windows的gbk編碼,而導致的中文亂碼!

  • 解析response內容
    dammit=UnicodeDammit(data,["utf-8","gbk"]) # 編碼
    data=dammit.unicode_markup 
    soup=BeautifulSoup(data,"lxml") # 解析網頁

1.2.3 獲取結點

  • 採用css選擇進行節點的獲取

舉個例子,其他類比

    lis=soup.select("ul[class='t clearfix'] li")

獲取到這裡的所有li就是

ul的屬性class = t clearfix的所有的li

1.2.4 資料儲存

  • 儲存到資料庫中(儲存到mysql資料庫中)

  • 匯入庫pymysql

import pymysql
  • 資料庫初始化連線
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'spider_ex' # 資料庫名
USERNAME = 'root'
PASSWORD = 'root'

# 開啟資料庫連線
conn = pymysql.connect(host=HOSTNAME, user=USERNAME,password=PASSWORD,database=DATABASE,charset='utf8')
# 使用 cursor() 方法建立一個遊標物件 cursor
cursor = conn.cursor()
  • 插入資料
def InsertData(count,date,weather,temp):
    a = temp.split(" ")
    global conn
    global cursor
    sql = "INSERT INTO ex2_1(序號, 地區, 日期,天氣資訊,溫度) VALUES (%s, %s, %s, %s, %s)"
    number = count
    area = "深圳"
    try:
        conn.commit()
        cursor.execute(sql,[number,area,date,weather,temp])
        print("插入成功")
    except Exception as err:
        print("插入失敗",err)
  • 使用原生sql語句進行插入儲存,並沒有使用orm。

實驗 2

2.1 題目

要求:用requests和自選提取資訊方法定向爬取股票相關資訊,並存儲在資料庫中。

2.2 思路

  • 觀察頁面的js包請求

可以先把多餘的請求刪去

然後點選新的頁面,就會出現這個關鍵的請求資訊。

檢視頁數和頁碼(比較第一第二頁的引數的區別)

  • 第一頁
  • 第二頁

可以看到這裡的引數pn會隨著頁數的增加而增加
所以可以知曉這個pn就是頁面的頁碼。

2.2.1 傳送請求

  • 編寫請求頭,以及引數。
import requests,json

headers = {
    'Connection': 'keep-alive',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Edg/94.0.992.38',
    'Accept': '*/*',
    'Referer': 'http://quote.eastmoney.com/',
    'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
}

params = (
    ('cb', 'jQuery1124049118572600550814_1634085098344'),
    ('pn', '2'),  # 第幾頁
    ('pz', '20'),  # 一頁多少個
    ('po', '1'),
    ('np', '1'),
    ('ut', 'bd1d9ddb04089700cf9c27f6f7426281'),
    ('fltt', '2'),
    ('invt', '2'),
    ('fid', 'f3'),
    ('fs', 'm:0 t:6,m:0 t:80,m:1 t:2,m:1 t:23'),
    ('fields', 'f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152'),
    ('_', '1634085098352'),
)

resp = requests.get('http://28.push2.eastmoney.com/api/qt/clist/get', headers=headers, params=params,  verify=False)
# 傳送請求

2.2.2 解析網頁

  • 由於返回的資料不是標準的json格式,所以要進行去頭去尾的操作。

建議把返回的格式複製到一些線上json的網站進行驗證,這樣才能保證json格式的正確。

res = resp.content[len("jQuery1124049118572600550814_1634085098344("):len(resp.content)-2]
res = str(res,'utf-8')
resp_json = json.loads(res)

2.2.3 獲取結點

  • json格式的處理方式非常簡單,找到key之後,直接遍歷即可。不需要複雜的操作。
for k in resp_json['data']['diff']:
    data["number"]=count,
    data["f12"]=k['f12'],
    data["f14"]=k['f14'],
    data["f2"]=k['f2'],
    data["f3"]=k['f3'],
    data["f4"]=k['f4'],
    data["f5"]=k['f5'],
    data["f6"]=k['f6'],
    data["f7"]=k['f7'],
    data["f15"]=k['f15'],
    data["f16"]=k['f16'],
    data["f17"]=k['f17'],
    data["f18"]=k['f18'],

注意: 一定要仔細看到每個引數對應的值,不然容易出錯,或遺漏

2.2.4 資料儲存

注意:這裡要進行一個數據的處理!

因為這個我們抓取到的資料是和顯示的是不一樣的,要進行一個處理。比如百分號單位

處理方法:

  • 百分號可以轉成字串直接相加
  • 如果是數字的話就直接像這樣判斷就好了
def formatDate(a):
    if a > 100000000:
        a = round(a/100000000,2)
        a = str(a) + '億'
    elif a > 10000:
        a = round(a/10000, 2)
        a = str(a) + '萬'
    return a

同 1.2.4

  • 貼結果

實驗 3

3.1 題目

爬取中國大學2021主榜(https://www.shanghairanking.cn/rankings/bcur/2021)所
有院校資訊,並存儲在資料庫中,同時將瀏覽器F12除錯分析的過程錄製Gif加入至部落格中。

3.2 思路

3.2.1 傳送請求

  • 引入庫並且編寫請求頭

請求頭是為了把爬蟲包裝成瀏覽器的正常訪問。

import urllib.request
import re

header = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36',
}
  • urllibrequests不同

urllib構造請求頭傳送請求是分開的,而requests是封裝在一起的。

url = "https://www.shanghairanking.cn/rankings/bcur/2021"
request = urllib.request.Request(url, headers=header) # 構造請求頭
r = urllib.request.urlopen(request)  # 傳送請求

3.2.2 解析網頁

  • decode() 是為了解碼成中文
  • replace('\n','') 是為了把回車去掉,方便後續的正則匹配。
html = r.read().decode().replace('\n','')

3.2.3 獲取結點

  • 分析網頁

我們很容易找到結點資訊,然後觀察節點資訊的結構。

  • 使用正則表示式獲取總體的節點資訊
ranking = re.findall("<td data-v-68e330ae>(.*?)</td></tr>",html)
  • 構造字典來儲存資料
uList =[]
for k in ranking:
    u = {
        "rank":"",
        "percent":"",
        "name":"",
        "socre":"",
    }
    name = re.findall("img alt=(.*?) onerror",k) 
    # 匹配出名字
    ranking = re.findall("                        (\d+)                    ",k)
    # 匹配出排名
    socre = re.findall("<td data-v-68e330ae>                        (.*?)                    ",k)
    # 匹配出分數
    u["rank"]=ranking[0]
    u["percent"]=socre[0]
    u["name"]=eval(name[0])
    u["socre"]=socre[1]
    uList.append(u)

3.2.4 儲存資料

同上 1.2.4

GIF:

程式碼地址

https://gitee.com/cocainecong/spider-experiment

心得

  1. 本次實驗重新複習了python連線mysql的語法,並且複習了原生sql語句的寫法。
  2. 多資料返回的時候,要仔細認真對好每一個引數的返回值與頁面上的值,防止會有資料對不上,資料對錯的情況。
  3. 要細心觀察資料的格式,要按照格式進行存放!!