python爬蟲解析頁面數據的三種方式


re模塊

  • re.S表示匹配單行
  • re.M表示匹配多行
    使用re模塊提取圖片url,下載所有糗事百科中的圖片

普通版

import requests
import re
import os

if not os.path.exists('image'):
    os.mkdir('image')
def get_page(number):
    '''
    頁數
    :param number:
    :return:
    '''
    if number == 1:
        url = 'https://www.qiushibaike.com/pic/'
    else:
        url='https://www.qiushibaike.com/pic/'+str(number)
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
    }
    page_text = requests.get(url=url,headers=headers).text

    img_list = re.findall('<div class="thumb">.*?<img src="(.*?)".*?>.*?</div>',page_text,re.S)
    for _url in img_list:
        img_url = 'https:'+_url
        response = requests.get(url=img_url,headers=headers)
        filename = img_url.split('/')[-1]
        file_path = 'image/%s'%filename
        with open(file_path,'wb') as f:
            f.write(response.content)
            print('爬取第%s頁數據中:%s'%(number,filename))

for i in range(1,35):
    get_page(i)

使用多線程下載

import requests
import re
import os
from concurrent.futures import ThreadPoolExecutor
if not os.path.exists('image'):
    os.mkdir('image')
def get_page(number):
    '''
    頁數
    :param number:
    :return:
    '''
    if number == 1:
        url = 'https://www.qiushibaike.com/pic/'
    else:
        url='https://www.qiushibaike.com/pic/'+'page/'+str(number)
    print(url)
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
    }
    page_text = requests.get(url=url,headers=headers).text

    img_list = re.findall('<div class="thumb">.*?<img src="(.*?)".*?>.*?</div>',page_text,re.S)
    for _url in img_list:
        img_url = 'https:'+_url
        response = requests.get(url=img_url,headers=headers)
        filename = img_url.split('/')[-1]
        file_path = 'image/%s'%filename
        with open(file_path,'wb') as f:
            f.write(response.content)
            print('爬取第%s頁數據中:%s'%(number,filename))

if __name__ == '__main__':
    pool = ThreadPoolExecutor(5)
    for i in range(1,36):
        pool.submit(get_page,i)

    pool.shutdown()
    print('爬取完畢')

xpath

xpath在爬蟲中的使用流程

  • 下載
  • 導包
  • 創建etree對象進行指定數據的解析
    • 本地:tree = etree.parse('本地文件路徑')
      • etree.xpath('xpath表達式')
    • 網絡:tree = etree.HTML('網絡請求到的頁面數據')
      • tree.xpath('xpath表達式')
#安裝
pip3 install lxml
#導包
from lxml import etree

常用的xpath表達式

屬性定位:
    #找到class屬性值為song的div標簽
    //div[@class="song"] 
層級&索引定位:
    #找到class屬性值為tang的div的直系子標簽ul下的第二個子標簽li下的直系子標簽a
    //div[@class="tang"]/ul/li[2]/a
邏輯運算:
    #找到href屬性值為空且class屬性值為du的a標簽
    //a[@href="" and @class="du"]
模糊匹配:
    //div[contains(@class, "ng")] # 包含
    //div[starts-with(@class, "ta")] #以什么開頭的
取文本:
    # /表示獲取某個標簽下的文本內容
    # //表示獲取某個標簽下的文本內容和所有子標簽下的文本內容
    //div[@class="song"]/p[1]/text() # 只能獲取當前標簽下面直系存儲的文本數據
    //div[@class="tang"]//text() # 獲取某一個標簽下,所有子標簽中存儲的文本數據
取屬性:
    //div[@class="tang"]//li[2]/a/@href

xpath簡單使用

from lxml import etree
import requests

url = 'https://www.qiushibaike.com/pic/'
page_text = requests.get(url=url).text

tree = etree.HTML(page_text)
url_list = tree.xpath('//div[@class="article block untagged mb15"]/div[2]/a/img/@src')

print(url_list)

xpath插件

  • xpath插件:就是可以直接將xpath表達式作用域瀏覽器的網頁中
  • 安裝:chorm瀏覽器 -> 更多工具 -> 擴展程序 -> 開啟開發者模式 -> 將xpath插件拖動到頁面
  • 快捷鍵
    • 開啟關閉:ctrl + shift + x

Element類型的對象可以繼續調用xpath函數,對該對象表示的局部內容進行指定內容解析

# 使用xpath提取出段子網的段子和標題
import requests
from lxml import etree

url = 'https://ishuo.cn/'
headers = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
}
page_text = requests.get(url=url,headers=headers).text

tree = etree.HTML(page_text)
li_list = tree.xpath('//div[@id="list"]/ul/li')
f = open('段子.text','w',encoding='utf-8')
for li in li_list:
    content = li.xpath('./div[@class="content"]/text()')[0]
    title = li.xpath('./div[@class="info"]/a/text()')[0]
    f.write("#####################\n"+title+":\n"+content+"\n\n")
print('寫入數據成功')

BeautifulSoup解析

BeautifulSoup庫是python獨有的庫,簡單便捷和高效

  • 核心思想:將將html文檔轉換成Beautiful對象,然后調用該對象中的屬性和方法進行html文檔指定內容的定位查找。

  • 導包

from bs4 import BeautifulSoup
  • 創建BeautifulSoup對象:
    • 如果html文檔的來源是來源於本地:Beautiful('open('本地的html文件')','lxml')
    • 如果html是來源於網絡:Beautiful(‘網絡請求到的頁面數據’,‘lxml’)

屬性和方法

  1. 根據標簽名查找:
soup.a  # 只能找到第一個符合要求的標簽
  1. 獲取屬性
soup.a.attrs  # 獲取a所有的屬性和屬性值,返回一個字典
soup.a.attrs['href']   # 獲取href屬性
soup.a['href']   # 也可簡寫為這種形式
  1. 獲取內容
soup.a.string   //text()
soup.a.text   //text()
soup.a.get_text()  //text()
# 如果標簽還有標簽,那么string獲取到的結果為None,而其它兩個,可以獲取文本內容
  1. find:找到第一個符合要求的標簽
soup.find('a') //找到第一個符合要求的
soup.find('a', title="xxx")
soup.find('a', alt="xxx")
soup.find('a', class_="xxx")
soup.find('a', id="xxx")
  1. find_All:找到所有符合要求的標簽
soup.find_All('a')
soup.find_All(['a','b']) # 找到所有的a和b標簽
soup.find_All('a', limit=2)  # 限制前兩個
  1. 根據選擇器選擇指定的內容
select:soup.select('#feng')

常見的選擇器:標簽選擇器(a)、類選擇器(.)、id選擇器(#)、層級選擇器

select選擇器返回永遠是列表,需要通過下標提取指定的對象

使用BeautifulSoup解析爬取三國演義小說全集

import requests
from bs4 import BeautifulSoup

url = 'http://www.shicimingju.com/book/sanguoyanyi.html'
headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
    }
page_text = requests.get(url=url,headers=headers).text

def get_content(url,fileobj):
    '''
    爬取頁面內容
    :param url:
    :param fileobj:
    :return:
    '''
    content_page = requests.get(url=url, headers=headers).text
    content_soup = BeautifulSoup(content_page, 'lxml')
    p_list = content_soup.select('.chapter_content > p')
    for p in p_list:
        fileobj.write('\n' + p.text + '\n\n')

soup = BeautifulSoup(page_text,'lxml')
a_list = soup.select('.book-mulu > ul > li > a')
f = open('三國演義.txt','w',encoding='utf-8')
for a in a_list:
    f.write('\n'+a.text)
    content_url = 'http://www.shicimingju.com'+a['href']
    get_content(content_url,f)
    print('爬取成功',a.text)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM