Python 爬蟲實戰 1

源:參加阿里雲的Python 爬蟲實戰課
本文代碼相關資源見本人CSDN主頁 ”正則表達式基礎.zip“。資源包括:
正則表達式

本文是課程 “Python網絡爬蟲快速入門到精通“ 的聽課筆記 + 自己跟隨的操作實戰。
課程作者
課程目錄
簡介

正則表達式

概念

基礎1

  • 全局匹配函數使用格式
re.compile(正則表達式).findall(源字符串)

普通字符   正常匹配
  \n     匹配換行符
  \t     匹配製表符
  \w     匹配字母、數字、下劃線
  \W     匹配除字母、數字下劃線
  \d     匹配十進制數字
  \D     匹配除十進制數字
  \s     匹配空白字符
  \S     匹配除空白字符
  [ab89x]     原子表,匹配ab89x 中的任意一個
  [^ab89x]     原子表,匹配除ab89x 中的任意一個字符

例子見同名 .py文件

基礎2

.     匹配除換行外任意一個字符
^     匹配開始位置[在原子表代表非,不在代表匹配開始位置]
$     匹配結束位置
*    前一個字符出現0\1\多次
?     前一個字符出現0\1次
+    前一個字符出現1\多次
{n}     前一個字符恰好出現n次
{n,}     前一個字符至少n次。
{n,m}     前一個字符至少n,至多m次
|      模式選擇符或
()     模式單元,通俗說就是,想提取出什麼內容,就在正則中用小括號將其括起來。

基礎3

貪婪模式:儘可能多地匹配
懶惰模式:儘可能少地匹配,精準模式
默認貪婪模式
如果出現如下組合,則代表爲懶惰模式
*?
+?

基礎4

模式修正符:在不改變正則表達式的情況下通過模式修正符使匹配結果發生更改
re.S     讓.也可以匹配多行
re.I     讓匹配時忽略大小寫

Python 代碼測試

對應上面四個基礎的測試代碼如下:

import re

print("-"*50, "基礎1", "-"*50)
src = "aliyunedu"
pat = re.compile("yu").findall(src)
print(pat)

src ="'aliyunedu'"
pat = re.compile("yun\n").findall(src)
print(pat)

src ='"aliyun\nedu"'
pat = re.compile("yun\n").findall(src)
print(pat)

src ="aliyun89787nedu"
pat = re.compile("\w\d\w\d\d\w").findall(src)
print(pat)
# 原子表
pat = re.compile("\w\d[nedu]\w").findall(src)
print(pat)
"""
-------------------------------------------------- 基礎1 --------------------------------------------------
['yu']
[]
['yun\n']
['n89787']
['87ne']
"""

# 基礎2
print("-"*50, "基礎2", "-"*50)
src ="aliyunnnnji87362387aoyubaidu"
pat = re.compile("ali...").findall(src)
print(pat)
pat = re.compile("^ali...").findall(src)
print(pat)
pat = re.compile("bai..$").findall(src)    # 注意,結束位置$ 是 \n
print(pat)
pat = re.compile("ali.*").findall(src)      # TIPS:默認貪婪,即默認儘可能多地進行匹配
print(pat)
pat = re.compile("aliyun+").findall(src)    # 多次n全部匹配出來
print(pat)
pat = re.compile("aliyun?").findall(src)    # 匹配1次最多
print(pat)
pat = re.compile("yun{1,2}").findall(src)    # 不超過2次,最少一次。
print(pat)
pat = re.compile("^al(i..)").findall(src)  #  相匹配括號裏面的
print(pat)

# 基礎3
print("-"*50, "基礎3", "-"*50)
src ="poythonyhjskjsa"
pat = re.compile("p.*y").findall(src)       # 儘可能多地匹配
print(pat)
pat = re.compile("p.*?y").findall(src)      # 儘可能少地匹配
print(pat)
pat = re.compile("p.+?y").findall(src)      # 儘可能少地匹配
print(pat)
src ="poythponyhjskjsa"
pat = re.compile("p.*y").findall(src)       # 儘可能多地匹配
print(pat)
pat = re.compile("p.*?y").findall(src)      # 儘可能少地匹配
print(pat)
pat = re.compile("p.+?y").findall(src)      # 儘可能少地匹配
print(pat)

# 基礎4
print("-"*50, "基礎4", "-"*50)
src ="Python"
pat = re.compile("pyt").findall(src)       # 匹配不到,因爲有大寫
print(pat)
pat = re.compile("pyt", re.I).findall(src)       # 可以匹配大小寫
print(pat)

src ="我是阿里雲大學\n歡迎來學習Python網絡爬蟲課程"
pat = re.compile("阿里.*?Python").findall(src)       # 匹配不到,因爲有換行
print(pat)
pat = re.compile("阿里.*?Python", re.S).findall(src)       # 可以匹配換行
print(pat)

XPath表達式

概念

/               逐層提取
text()              提取標籤下面的文本
//標籤名**           提取所有名爲**的標籤
//標籤名[@屬性=‘屬性值’]    提取屬性爲XX的標籤
@屬性名            代表取某個屬性值

<!DOCTYPE html>
<html>
    <head>
        <title>主頁</title>
    </head>
    <body>
        <p>abc</p>
        <p>bbbvb</p>
        <a href="//qd.alibaba.com/go/v/pcdetail" target="_top">安全推薦</a>
        <a href="//qd.alibaba.com/go/v/pcdetail" target="_top">安全推薦2</a>
        <div class="J_AsyncDC" data-type="dr">
            <div id="official-remind">明月幾時有</div>
        </div>
    </body>
</html>

分析以下XPath 表達式提取的內容:
提取標題=主頁
/html/head/title/text()
提取所有的div標籤
//div
提取div中

標籤的內容
//div[@class=“tools”]
提取p標籤下的所有文本=[abc, bbbvb]
//p/text()
提取所有的a標籤
//a
提取所有的div標籤,且標籤屬性的id有定位=明月幾時有
//div[@id=“official-remind”]/text()
提取所有a標籤下的href屬性值=上面代碼的兩個網址
//a/@href

Python 代碼測試

from lxml import etree

print("-"*50, "測試: 打印 html 應該顯示內容", "-"*50)
html = etree.parse('XPath_test.html')
html_data = html.xpath('//*')      # 打印是一個列表需要遍歷
print(html_data)
print("-"*50)
for i in html_data:
    print(i.text)

print("-"*50, "測試: 打印 html 所有文本內容", "-"*50)
html = etree.parse('XPath_test.html')
html_data = etree.tostring(html, pretty_print=True)
res = html_data.decode('utf-8')
print(res)

print("-"*50, "測試: XPath表達式測試=標題提取", "-"*50)
html = etree.parse('XPath_test.html')
html_data = html.xpath('/html/head/title/text()')
for i in html_data:
    print(i)

print("-"*50, "測試: XPath表達式測試=所有div標籤內容提取", "-"*50)
html_data = html.xpath('//div')
for i in html_data:
    print(i)

print("-"*50, "測試: XPath表達式測試=所有div標籤指定屬性的內容提取", "-"*50)
html_data = html.xpath('//div[@id="official-remind"]/text()')
for i in html_data:
    print(i)

print("-"*50, "測試: XPath表達式測試=所有p標籤內容提取", "-"*50)
html_data = html.xpath('//p/text() ')
for i in html_data:
    print(i)

print("-"*50, "測試: XPath表達式測試=所有a標籤內容提取", "-"*50)
html_data = html.xpath('//a')
for i in html_data:
    print(i)

print("-"*50, "測試: XPath表達式測試=所有a標籤href屬性的內容提取", "-"*50)
html_data = html.xpath('//a/@href')
for i in html_data:
    print(i)

後注

來找自己瀏覽器的Headers屬性。
–(1)打開任意網頁,按F12,並選擇網絡(network)
–(2)任意點擊網頁連接,使其發生動作。點擊,觸發一個動作,User-Agent字樣的一串信息即是。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章