1. 程式人生 > >爬蟲——爬蟲中使用正則表達式

爬蟲——爬蟲中使用正則表達式

txt文件 點擊 頁碼 range safari 頁面 gen odin ace

下面我們嘗試爬取內涵段子網站:http://www.neihan8.com/article/list_5_1.html

打開之後,當你進行翻頁的時候,不能註意到,url地址的變化:

  • 第一頁url: http: //www.neihan8.com/article/list_5_1 .html

  • 第二頁url: http: //www.neihan8.com/article/list_5_2 .html

  • 第三頁url: http: //www.neihan8.com/article/list_5_3 .html

  • 第四頁url: http: //www.neihan8.com/article/list_5_4 .html

這樣,我們把url規律找到了,要想爬取所有的段子,只需要修改一個參數即可。下面,我們就開始一步一步將所有的段子爬取下來。

第一步:獲取網頁數據(網頁上全部內容)

1.按照我們之前的用法,我們需要寫一個加載頁面的方法。

這裏我們定義一個類,將url請求作為一個成員方法處理。

我們創建一個duanzi_spider.py文件。

然後定義一個Spider類,並且添加一個加載頁面的成員方法

#!/usr/bin/python3
# -*- conding:utf-8 -*-
__author__ = ‘mayi‘

import requests

class Spider(object):
    """
    一個爬蟲類
    """
    def loadPage(self, url):
        """
        下載指定url頁面的內容
        :return:
        """
        # User-Agent頭
        header = {‘User-Agent‘:‘Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36‘}
        response = requests.get(url = url, headers = header)
        html = response.content.decode("gb18030")
        
        # 打印頁面內容
        print(html)
        
        # 返回頁面內容
        return html

2.寫main函數測試loadPage()方法

if __name__ == ‘__main__‘:
    # 實例化類對象
    my_spider = Spider()
    # 讓用戶輸入需爬取頁面的頁碼
    page = int(input("請輸入你需要爬取的頁碼:"))
    # 拼接用戶需爬取頁面的url地址
    url = "http://www.neihan8.com/article/list_5_{}.html".format(page)
    html = my_spider.loadPage(url)

第二步:篩選數據

我們已經得到了整個頁面的數據。但是,裏面有很多內容我們並不需要,所以下一步我們需要對上面爬取的內容進行篩選。如果篩選,這裏就用到了我們前面講到的正則表達式。

  • 首先
import re
  • 然後:在我們得到的html中進行篩選匹配。

我們需要一個匹配規則:

我們可以打開內涵段子的網頁,鼠標點擊右鍵“查看源代碼”,你會發現,我們需要的每個段子的內容都是在一個<div>標簽中,而且每個div都有一個屬性class="f18 mb20"

技術分享

所以,我們只需要匹配到網頁中所有<div class="f18 mb20">到</div>的數據就可以了。

根據正則表達式,我們可以推算出一個公式是:

<div class="f18 mb20">(.*?)</div>
  • 這個表達式實際上就是匹配到所有div中class="f18 mb20"裏面的內容
  • 然後將這個正則應用到代碼中,我們會得到以下代碼:
#!/usr/bin/python3
# -*- conding:utf-8 -*-
__author__ = ‘mayi‘

import requests
import re

class Spider(object):
    """
    一個爬蟲類
    """
    def loadPage(self, url):
        """
        下載指定url頁面的內容
        :return:
        """
        # User-Agent頭
        header = {‘User-Agent‘:‘Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36‘}
        response = requests.get(url = url, headers = header)
        html = response.content

        return html.decode("gb18030")

    def screenPage(self, html):
        """
        篩選html內容,返回列表
        :param html:
        :return:
        """
        # <div class="f18 mb20">...</div>
        pattern = re.compile(r‘<div class="f18 mb20">(.*?)</div>‘, re.S)
        item_list = pattern.findall(html)

        return item_list

if __name__ == ‘__main__‘:
    # 實例化類對象
    my_spider = Spider()
    # 讓用戶輸入需爬取頁面的頁碼
    page = int(input("請輸入你需要爬取的頁碼:"))
    # 拼接用戶需爬取頁面的url地址
    url = "http://www.neihan8.com/article/list_5_{}.html".format(page)
    # 下載網頁內容
    html = my_spider.loadPage(url)
    # 篩選數據
    item_list = my_spider.screenPage(html)
  • 這裏需要註意的是re.S是正則表達式中匹配的一個參數。
  • 如果沒有re.S,則是只匹配一行中有沒有符合規則的字符串,如果沒有則下一行重新匹配。
  • 如果加上re.S則是將所有的字符串作為一個整體進行匹配,findall將所有匹配到的結果返回列表中。

第三步:保存數據

我們可以將所有的段子存放在文件中。

    def writePage(self, list):
        """
        以追加的形式存儲篩選後的內容
        :param list: 篩選後的數據,列表形式
        :return:
        """
        with open(self.file_name, "a", encoding = "utf-8") as f:
            for content in list:
                # 段子內容:因為段子中有很多<p>,</p>,<br />。。。,還有一些轉義字符。在這裏作下替換
                content = content.replace("…", "…").replace("“", "“").replace("”", "”")
                content = content.replace(" ", "").replace("\t", "").replace(":", ":")
                content = content.replace("<p>", "").replace("</p>", "").replace("<br />", "").replace(" ", "")
                content = content.replace("\u3000", "").replace("\r\n\r\n", "\r\n")
                content = content.strip()

                # 寫入一個段子的內容
                f.write(content)
                # 我是分割線
                f.write("*" * 30)

第四步:完整的程序

#!/usr/bin/python3
# -*- conding:utf-8 -*-
__author__ = ‘mayi‘

import requests
import re

class Spider(object):
    """
    一個爬蟲類
    """
    def __init__(self, start_page, end_page):
        """
        類的初始化函數
        :param start_page:
        :param end_page:
        :return:
        """
        self.start_page = start_page
        self.end_page = end_page
        self.file_name = "duanzi.txt"

    def loadPage(self, url):
        """
        下載指定url頁面的內容
        :return:
        """
        # User-Agent頭
        header = {‘User-Agent‘:‘Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36‘}
        response = requests.get(url = url, headers = header)
        html = response.content

        return html.decode("gb18030")

    def screenPage(self, html):
        """
        篩選html內容,返回列表
        :param html:
        :return:
        """
        # <div class="f18 mb20">...</div>
        pattern = re.compile(r‘<div class="f18 mb20">(.*?)</div>‘, re.S)
        item_list = pattern.findall(html)

        return item_list

    def writePage(self, list):
        """
        以追加的形式存儲篩選後的內容
        :param list: 篩選後的數據,列表形式
        :return:
        """
        with open(self.file_name, "a", encoding = "utf-8") as f:
            for content in list:
                # 段子內容:因為段子中有很多<p>,</p>,<br />。。。,還有一些轉義字符。在這裏作下替換
                content = content.replace("…", "…").replace("“", "“").replace("”", "”")
                content = content.replace(" ", "").replace("\t", "").replace(":", ":")
                content = content.replace("<p>", "").replace("</p>", "").replace("<br />", "").replace(" ", "")
                content = content.replace("\u3000", "").replace("\r\n\r\n", "\r\n").replace("\r\n", "\n")
                content = content.strip()

                # 寫入一個段子的內容
                f.write(content)
                # 我是分割線
                f.write("*" * 30)

    def run(self):
        """
        讓爬蟲開始工作
        :return:
        """
        # 循環處理我們需要爬取的頁面
        for page in range(self.start_page, self.end_page + 1):
            # 拼接當前頁碼page的url地址
            url = "http://www.neihan8.com/article/list_5_{}.html".format(str(page))
            print("正在下載第{}頁".format(str(page)))
            # 下載url對應的全部內容
            html = self.loadPage(url)
            # 篩選數據
            item_list = self.screenPage(html)
            # 存儲篩選後的數據
            self.writePage(item_list)

# 主函數
if __name__ == ‘__main__‘:
    # 讓用戶輸入需爬取頁面的起始頁碼
    start_page = int(input("請輸入您需要爬取的起始頁:"))
    # 讓用戶輸入需爬取頁面的終止頁碼
    end_page   = int(input("請輸入您需要爬取的終止頁:"))
    # 實例化類對象
    mySpider = Spider(start_page, end_page)
    # 讓爬蟲開始工作
    mySpider.run()

最後,我們執行上面的代碼,完成後查看當前路徑下的duanzi.txt文件,裏面已經有我們要的內涵段子。

以上便是一個非常精簡的小爬蟲程序,使用起來很方便,如果想要爬取其他網站的信息,只需要修改其中某些參數和一些細節就行了。

爬蟲——爬蟲中使用正則表達式