爬蟲入門經典(八) | 一文帶你快速爬取股吧

2020-10-25 12:00:33

  大家好,我是不溫卜火,是一名計算機學院巨量資料專業大三的學生,暱稱來源於成語—不溫不火,本意是希望自己性情溫和。作為一名網際網路行業的小白,博主寫部落格一方面是為了記錄自己的學習過程,另一方面是總結自己所犯的錯誤希望能夠幫助到很多和自己一樣處於起步階段的萌新。但由於水平有限,部落格中難免會有一些錯誤出現,有紕漏之處懇請各位大佬不吝賜教!暫時只在csdn這一個平臺進行更新,部落格主頁:https://buwenbuhuo.blog.csdn.net/
1

PS:由於現在越來越多的人未經本人同意直接爬取博主本人文章,博主在此特別宣告:未經本人允許,禁止轉載!!!


2


giao!連續用了正則爬取了兩個網站。博主表示是抗拒的。所以本次博主任性的選擇了用xpath爬取股吧的相關資訊。

3

一、lxml語法的簡單回顧

4
5
6
7

二、網頁的簡單分析

咳咳,爬取網站資訊,沒有網址可怎麼行呢?安排:
http://guba.eastmoney.com/
在開啟網頁之後,我們發現介面是這樣的
8
通過檢視頁面,我們可以看到標紅部分就是我們準備爬取的內容。當然了,在進行頁面解析之前,我們還有一件事情要做。我們既然要爬取內容,就不可能只爬取一頁內容對吧。我們先來分析下每一頁之間有沒有關聯,首先我們看下後幾頁

https://guba.eastmoney.com/default,99_2.html
https://guba.eastmoney.com/default,99_3.html
https://guba.eastmoney.com/default,99_4.html

以此,我們判斷出第一頁是不是

https://guba.eastmoney.com/default,99_1.html

我們可以驗證下
9
🆗,我們的猜想是正確的。因此,我們知道我們需要剛開始的連結分別為

base_url = "http://guba.eastmoney.com/"
start_url = "http://guba.eastmoney.com/default,99_1.html"

10

三、主體部分分析及解析提取

開啟開發者選項,我們可以看到對應的關係
11
這個時候,我們的思路應該是通過xpath先把我們所要解析的單個主提先提取出來,然後迴圈提取、追加。

html_obj = etree.HTML(html)
# 使用xpath語法提取
li_list = html_obj.xpath('//ul[@class="newlist"]/li')
print(li_list)
print(len(li_list))

12
從上圖我們可以看到我們已經獲取了所有的<li></li>標籤。下面就是把他們每個比如閱讀、評論等這些分別提取出來。

  • 1.閱讀
    13
  • 2.評論
    14
  • 3.標題
    15
  • 4.URL
    16
  • 5.作者
    17
  • 6.更新時間
    18
    分析完成!下面就可以看下程式碼實現了:
    19
            item = {}
            item["read"] = li.xpath("./cite[1]/text()")[0].strip()
            item["comment"] = li.xpath("./cite[2]/text()")[0].strip()
            item["name"] = li.xpath("./span/a[1]/text()")[0]
            if li.xpath("./span/a[2]"):
                item["title"] = li.xpath("./span/a[2]/text()")[0]
            else:
                item["title"] = ""
            if li.xpath("./span/a[2]/@href"):
                item["url"] = self.base_url + li.xpath("./span/a[2]/@href")[0]
            else:
                item["url"] = ""
            item["author"] = li.xpath("./cite[3]/a/font/text()")[0]
            item["date"] = li.xpath("./cite[4]/text()")[0].strip()
            items.append(item)

			print(items)

20
我們可以看到我們得到的結果是正確的。至於為什麼上面新增的有判斷語句,是因為每個網站都有其反爬手段,這裡博主直接給出了完整程式碼。如果有感興趣的童鞋,可以把判斷語句去掉,自行檢視驗證,並修改。這樣可以增強記憶。

好了,內容方面已經解析完成,下面我們就需要梳理翻頁的思路了。

21
我們通過上面的分析

https://guba.eastmoney.com/default,99_1.html
https://guba.eastmoney.com/default,99_2.html
https://guba.eastmoney.com/default,99_3.html
https://guba.eastmoney.com/default,99_4.html

可以看到每一頁之間都是有聯絡的,每一頁的網址也只是變動了一個數位而已,並且我們通過檢視網頁,發現網頁也只有12頁,因此我們可以這樣完成模擬

start_url = "http://guba.eastmoney.com/default,99_{}.html"

for i in range(1,13):
    # 獲取url
    pageLink = start_url.format(i)
    print(pageLink)

22
不過博主在此給出的是另一種寫法

通過這種解析方式可以自動獲取下一頁的網址
23
通過這樣,我們只需通過拼接就可以達到每一頁的網址

        #提取下一頁
        next_url = html_obj.xpath('//a[contains(text(),"下一頁")]/@href')
        if next_url:
            next_url = self.base_url + next_url[0]
            print(next_url)

四、完整程式碼

# encoding: utf-8
'''
  @author 李華鑫
  @create 2020-10-07 9:20
  Mycsdn:https://buwenbuhuo.blog.csdn.net/
  @contact: 459804692@qq.com
  @software: Pycharm
  @file: 爬股吧.py
  @Version:1.0
  
'''
import requests
import re
import time
import random
from lxml import etree


class Spider:
    def __init__(self):
        self.base_url = "http://guba.eastmoney.com/"
        self.start_url = "http://guba.eastmoney.com/default,99_1.html"
        self.headers = {
            "user-agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
        }
        self.items = []
        self.index = 1

    def get_content(self, url):
        """獲取url對應的內容"""
        time.sleep(random.random()*3)
        response = requests.get(url=url, headers=self.headers)
        return response.content.decode("utf-8")

    def parse_html(self, html):
        """解析html獲取資料"""
        # 解析html
        html_obj = etree.HTML(html)
        # 使用xpath語法提取
        li_list = html_obj.xpath('//ul[@class="newlist"]/li')
        # 迴圈
        for li in li_list:
            print(self.index)
            item = {}
            item["read"] = li.xpath("./cite[1]/text()")[0].strip()
            item["comment"] = li.xpath("./cite[2]/text()")[0].strip()
            item["name"] = li.xpath("./span/a[1]/text()")[0]
            if li.xpath("./span/a[2]"):
                item["title"] = li.xpath("./span/a[2]/text()")[0]
            else:
                item["title"] = ""
            if li.xpath("./span/a[2]/@href"):
                item["url"] = self.base_url + li.xpath("./span/a[2]/@href")[0]
            else:
                item["url"] = ""
            item["author"] = li.xpath("./cite[3]/a/font/text()")[0]
            item["date"] = li.xpath("./cite[4]/text()")[0].strip()
            self.items.append(item)
            self.index+=1

        #提取下一頁
        next_url = html_obj.xpath('//a[contains(text(),"下一頁")]/@href')
        if next_url:
            next_url = self.base_url + next_url[0]
            html = self.get_content(next_url)
            self.parse_html(html)

    def save(self):
        """儲存"""
        with open("./股吧.txt", "a", encoding="utf-8") as file:
            for item in self.items:
                file.write(",".join(item.values()))
                file.write("\n")

    def start(self):
        print("爬蟲開始...")
        self.parse_html(self.get_content(self.start_url))
        print("爬蟲結束...")
        print("儲存開始...")
        self.save()
        print("儲存結束...")


if __name__ == '__main__':
    Spider().start()

五、儲存成功截圖

25
24
17

美好的日子總是短暫的,雖然還想繼續與大家暢談,但是本篇博文到此已經結束了,如果還嫌不夠過癮,不用擔心,我們下篇見!


18

  好書不厭讀百回,熟讀課思子自知。而我想要成為全場最靚的仔,就必須堅持通過學習來獲取更多知識,用知識改變命運,用部落格見證成長,用行動證明我在努力。
  如果我的部落格對你有幫助、如果你喜歡我的部落格內容,請「點贊」 「評論」「收藏」一鍵三連哦!聽說點讚的人運氣不會太差,每一天都會元氣滿滿呦!如果實在要白嫖的話,那祝你開心每一天,歡迎常來我部落格看看。
  碼字不易,大家的支援就是我堅持下去的動力。點贊後不要忘了關注我哦!

19
20