爬蟲初級操做(二)

本篇內容爲 python 網絡爬蟲初級操做的簡單介紹,內容主要有如下 2 部分:html

  • 解析網頁
  • 數據庫

解析網頁

通常來講,解析網頁有三種方式:正則表達式、BeautifulSoup、lxml。其中正則表達式較難,BeautifulSoup 適合初學者,能夠快速掌握提取網頁中數據的方法。python

正則表達式

常見的正則字符和含義以下:mysql

.    匹配任意字符,除了換行符
*     匹配前一個字符 0 次或屢次
+    匹配前一個字符 1 次或屢次
?    匹配前一個字符 0 次或 1 次

^    匹配字符串開頭
$    匹配字符串末尾

()    匹配括號內表示式,也表示一個組

\s    匹配空白字符
\S    匹配任何非空白字符

\d    匹配數字,等價於[0-9]
\D    匹配任何非數字,等價於[^0-9]

\w    匹配字母數字,等價於[A-Za-z0-9]
\W    匹配非字母數字,等價於[^A-Za-z0-9]

[]    用來表示一組字符

Python 正則表達式有如下 3 種方法:
re.match 方法:從字符串起始位置匹配一個模式,若是從起始位置匹配了,match()就返回none。
語法 re.match(pattern, string, flags=0)
pattern:正則表達式
string:要匹配的字符串
flags:控制正則表達式的匹配方式,如 是否區分大小寫、多行匹配等git

re.search方法:只能從字符串的起始位置進行匹配。github

find_all方法:能夠找到全部的匹配。正則表達式

BeautifulSoup

BeautifulSoupHTMLXML 文件中提取數據。首先須要使用命令行來進行安裝:sql

pip install bs4

在使用的時候須要導入:mongodb

from bs4 import BeautifulSoup

例如使用 BeautifulSoup 獲取博客主頁文章的標題,代碼和註釋以下:數據庫

import requests
from bs4 import BeautifulSoup

link = 'http://www.santostang.com/'
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'}
r = requests.get(link, headers=headers)
# 將網頁響應體的字符串轉換爲soup對象
soup = BeautifulSoup(r.text, 'html.parser')
first_title = soup.find('h1', class_='post-title').a.text.strip()
print('第一篇文章的標題是:', first_title)

title_list = soup.find_all('h1', class_='post-title')

for i in range(len(title_list)):
    title = title_list[i].a.text.strip()

    print('第 %s 篇文章的標題是: %s' % (i+1, title))

運行獲得結果:
圖片描述api

成功抓取到所需內容。

關於 BeautifulSoup, 咱們最後再來看一個實戰項目:爬取北京二手房價格。代碼以下:

import requests
from bs4 import BeautifulSoup
import time

headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'}

for i in range(1,11):
    link = 'https://beijing.anjuke.com/sale/'
    r = requests.get(link, headers=headers)
    print('第', i, '頁')

    soup = BeautifulSoup(r.text, 'lxml')
    house_list = soup.find_all('li', class_='list-item')

    for house in house_list:
        name = house.find('div', class_='house-title').a.text.strip()
        price = house.find('span', class_='price-det').text.strip()
        price_area = house.find('span', class_='unit-price').text.strip()

        no_room = house.find('div', class_='details-item').span.text
        area = house.find('div', class_='details-item').contents[3].text
        floor = house.find('div', class_='details-item').contents[5].text
        year = house.find('div', class_='details-item').contents[7].text
        broker = house.find('span', class_='brokername').text
        broker = broker[1:]
        address = house.find('span', class_='comm-address').text.strip()
        address = address.replace('\xa0\xa0\n                 ', '    ')
        tag_list = house.find_all('span', class_='item-tags')
        tags = [i.text for i in tag_list]
        print(name, price, price_area, no_room, area, floor, year, broker, address, tags)
    time.sleep(5)

這樣就成功爬取了安居客上前 10 頁的北京二手房價格。

數據庫

數據存儲分爲兩種,存儲在文件(TXT和CSV)中和存儲在數據庫(MySQL關係數據庫和MongoDB數據庫)中。

CSV (Comma-Separated Values)是逗號分隔值的文件格式,其文件以純文本的形式存儲表格數據(數字和文本)。
CSV 文件的每一行都用換行符分隔,列與列之間用逗號分隔。

MySQL是一種關係數據庫管理系統,所使用的是SQL語言,是訪問數據庫最經常使用的標準化語言。關係數據庫(創建在關係模型基礎上的數據庫)將數據保存在不一樣的表中,而不是將全部數據放在一個大倉庫內,這樣就增長了寫入和提取的速度,數據的存儲也比較靈活。

關於存儲在文件的方法這裏再也不贅述,下面首先介紹如何存儲至MySQL數據庫。

你須要先到官網下載並安裝 MySQL數據庫,博主用的是 macOS Sierra 系統,在安裝完成後,打開系統偏好設置,以下圖:
圖片描述

最下方出現 MySQL的圖標,打開並鏈接,以下圖所示:
圖片描述

打開終端,在終端中輸入添加MySQL路徑的命令:

PATH="$PATH":/usr/local/mysql/bin

繼續輸入登陸到MySQL的命令:mysql -u root -p,而後輸入密碼便可成功登陸。成功登陸界面以下:
圖片描述

接下來介紹MySQL的基本操做:

  • 建立數據庫

圖片描述

  • 建立數據表

建立數據表必須指明每一列數據的名稱(column_name)和類別(column_type)。
圖片描述
在上圖中,建立了 4 個變量:id, url, content, created_time。其中id的類別是整數INT,屬性爲本身增長(AUTO_INCREMENT)。新添加數據的數值會自動加 1。PRIMARY KEY的關鍵字用於將id定義爲主鍵。

urlcontent的類別是可變長度的字符串VARCHAR,括號中的數字表明長度的最大值,NOT NULL表示urlcontent不能爲空。created_time爲該數據添加時間,不須要設置,由於有時間戳,它會自動根據當時的時間填入。

建立數據表後,可查看數據表的結構:
圖片描述

  • 在數據表中插入數據

圖片描述

這裏插入了urlcontent兩個屬性,id是自動遞增的,created_time是數據加入的時間戳,這兩個變量會自動填入。

  • 從數據表中提取數據

圖片描述

由上圖,咱們能夠看到提取數據有 3 種方法:
(1)將id等於 1 的數據行提取出來;
(2)提取只看部分字段的數據;
(3)提取包含部份內容的數據。

  • 刪除數據

圖片描述

⚠️注意,若是沒有指定 WHERE 子句,用DELETE FROM urls將會致使MySQL表中的全部記錄被刪除,即誤刪除整張表。

  • 修改數據

圖片描述

因爲idcreated_time是數據庫自動填入的,所以這一行數據的id爲 2。

更多操做可參考菜鳥教程

下面介紹使用Python操做MySQL數據庫,依次使用下令命令安裝mysqlclient

brew install mysql
export PATH=$PATH:/usr/local/mysql/bin
pip install MySQL-Python
pip3 install mysqlclient

出現下列文字即安裝成功:
圖片描述

Python操做MySQL數據庫,咱們以在博客爬取標題和 url 地址爲例,具體代碼和解釋以下:

#coding=UTF-8
import MySQLdb
import requests
from bs4 import BeautifulSoup

# connect() 方法用於建立數據庫的鏈接,裏面能夠指定參數:用戶名,密碼,主機等信息
#這只是鏈接到了數據庫,要想操做數據庫須要建立遊標
conn = MySQLdb.connect(host='localhost', user='root', passwd='your_password', db='MyScraping', charset='utf8')
# 經過獲取到的數據庫鏈接conn下的cursor()方法來建立遊標。
cur=conn.cursor()

link = 'http://www.santostang.com/'
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'}
r = requests.get(link, headers=headers)

soup = BeautifulSoup(r.text, 'html.parser')
title_list = soup.find_all('h1', class_='post-title')
for eachone in title_list:
    url = eachone.a['href']
    title = eachone.a.text.strip()
    # 建立數據表,經過遊標cur 操做execute()方法能夠寫入純sql語句。經過execute()方法中寫如sql語句來對數據進行操做
    cur.execute('INSERT INTO urls (url, content) VALUES (%s, %s)', (url, title))

cur.close()
conn.commit()
conn.close()

最後,咱們來介紹如何存儲至MongoDB數據庫。

首先要知道NoSQL泛指非關係型數據庫,數據之間無關係,具備很是高的讀寫性能,而MongoDB是其中很是流行的一種數據庫。它是一種關係數據庫管理系統,所使用的是SQL語言,是訪問數據庫最經常使用的標準化語言。

下面仍以上述的在博客爬取標題和 url 地址爲例。

第一步鏈接 MongoDB客戶端,而後鏈接數據庫blog_database,再選擇該數據的集合blog。若是它們不存在,就會自動建立一個,代碼示例以下:

from pymongo import MongoClient

client = MongoClient('localhost', 27017)
db = client.blog_database
collection = db.blog

第二步爬取博客主頁的全部文章標題存儲至MongoDB數據庫,代碼以下:

import requests
import datetime
from bs4 import BeautifulSoup
from pymongo import MongoClient

client = MongoClient('localhost', 27017)
db = client.blog_database
collection = db.blog

link = 'http://www.santostang.com/'
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'}
r = requests.get(link, headers=headers)

soup = BeautifulSoup(r.text, 'html.parser')
title_list = soup.find_all('h1', class_='post-title')
for eachone in title_list:
    url = eachone.a['href']
    title = eachone.a.text.strip()
    post = {'url': url,
            'title': title,
            'date': datetime.datetime.utcnow()

    }
    collection.insert_one(post)

重點在最後一部分的代碼,首先將爬蟲獲取的數據存入post的字典中,而後使用insert_one加入集合collection中。

最後,啓動MongoDB查看結果。

打開終端輸入:

sudo mongod --config /usr/local/etc/mongod.conf

確認權限後,保持當前終端不關,新建終端依次輸入:

mongod

mongo

出現如下文字表示鏈接成功:
圖片描述

而後,輸入:

use blog_database

db.blog.find().pretty()

就查詢到數據集合的數據了,以下圖所示:
圖片描述

同時注意到,它是JSON格式的。

更多使用 Python 來操做 MongoDB 數據庫的知識,能夠參考 PyMongo官網


本文爲崔慶才博客和唐鬆的《Python網絡爬蟲從入門到實踐》學習記錄與總結,具體內容可參考兩者。博主在學習過程當中的練習代碼也已上傳至 GitHub

不足之處,歡迎指正。

相關文章
相關標籤/搜索