1. 程式人生 > 程式設計 >Python爬蟲爬取、解析資料操作示例

Python爬蟲爬取、解析資料操作示例

本文例項講述了Python爬蟲爬取、解析資料操作。分享給大家供大家參考,具體如下:

爬蟲 噹噹網 http://search.dangdang.com/?key=python&act=input&page_index=1

  1. 獲取書籍相關資訊
  2. 面向物件思想
  3. 利用不同解析方式和儲存方式

引用相關庫

import requests
import re
import csv
import pymysql
from bs4 import BeautifulSoup
from lxml import etree
import lxml
from lxml import html

類程式碼實現部分

class DDSpider(object):
  #物件屬性 引數 關鍵字 頁數
  def __init__(self,key='python',page=1):
    self.url = 'http://search.dangdang.com/?key='+key+'&act=input&page_index={}'
    self.page = page
    self.headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/53.0.2785.116 Safari/537.36'}

    
  #私有物件方法
  def __my_url(self):
    my_url = []
    if self.page < 1:
      my_page = 2
    else:
      my_page = self.page+1
    #迴圈遍歷每一頁
    for i in range(1,my_page):
      my_url.append(self.url.format(i))
    return my_url
  
  #私有物件方法 請求資料
  def __my_request(self,url,parser_type):
    #迴圈遍歷每一頁
    response = requests.get(url=url,headers=self.headers)
    if response.status_code == 200:
      return self.__my_parser(response.text,parser_type)
    else:
      return None
    
  #私有物件方法 解析資料 1 利用正則 2 bs4 3 xpath
  def __my_parser(self,html,my_type=1):
    if my_type == 1:
      pattern = re.compile('<p.*?class=[\'\"]name[\'\"].*?name=[\'\"]title[\'\"].*?<a.*?title=[\'\"](.*?)[\'\"].*?href=[\'\"](.*?)[\'\"].*?name=[\'\"]itemlist-title[\'\"].*?<p class=[\'\"]detail[\'\"].*?>(.*?)</p>.*?<span.*?class=[\'\"]search_now_price[\'\"].*?>(.*?)</span>.*?<p.*?class=[\'\"]search_book_author[\'\"].*?><span>.*?<a.*?name=[\'\"]itemlist-author[\'\"].*?title=[\'\"](.*?)[\'\"].*?</span>',re.S)
      result = re.findall(pattern,html)
    elif my_type == 2:
      soup = BeautifulSoup(html,'lxml')
      result = []
      title_url = soup.find_all('a',attrs={'name':'itemlist-title'})
      for i in range(0,len(title_url)):
        title = soup.find_all('a',attrs={'name':'itemlist-title'})[i].attrs['title']
        url = soup.find_all('a',attrs={'name':'itemlist-title'})[i].attrs['href']
        price = soup.find_all('span',attrs={'class':'search_now_price'})[i].get_text()
        author = soup.find_all('a',attrs={'name':'itemlist-author'})[i].attrs['title']
        desc = soup.find_all('p',attrs={'class':'detail'})[i].get_text()
        my_tuple = (title,desc,price,author)
        result.append(my_tuple)
    else:
      html = etree.HTML(html)
      li_all = html.xpath('//div[@id="search_nature_rg"]/ul/li')
      result = []
      for i in range(len(li_all)):
        title = html.xpath('//div[@id="search_nature_rg"]/ul/li[{}]/p[@class="name"]/a/@title'.format(i+1))
        url = html.xpath('//div[@id="search_nature_rg"]/ul/li[{}]/p[@class="name"]/a/@href'.format(i+1))
        price = html.xpath('//div[@id="search_nature_rg"]/ul/li[{}]//span[@class="search_now_price"]/text()'.format(i+1))
        author_num = html.xpath('//div[@id="search_nature_rg"]/ul/li[{}]/p[@class="search_book_author"]/span[1]/a'.format(i+1))
        if len(author_num) != 0:
          #有作者 a標籤
          author = html.xpath('//div[@id="search_nature_rg"]/ul/li[{}]/p[@class="search_book_author"]/span[1]/a[1]/@title'.format(i+1))
        else:
          #沒有作者 a標籤
          author = html.xpath('//div[@id="search_nature_rg"]/ul/li[{}]/p[@class="search_book_author"]/span[1]/text()'.format(i+1))
        desc = html.xpath('//div[@id="search_nature_rg"]/ul/li[{}]/p[@class="detail"]/text()'.format(i+1))
        my_tuple = (" ".join(title)," ".join(url)," ".join(desc)," ".join(price)," ".join(author))
        result.append(my_tuple)
        
    return result
  
  #私有物件方法 儲存資料 1 txt 2 csv 3 mysql
  def __my_save(self,data,save_type=1):
    #迴圈遍歷
    for value in data:
      if save_type == 1:
        with open('ddw.txt','a+',encoding="utf-8") as f:
          f.write('【名稱】:{}【作者】:{}【價格】:{}【簡介】:{}【連結】:{}'.format(value[0],value[4],value[3],value[2],value[1]))
      elif save_type == 2:
        with open('ddw.csv',newline='',encoding='utf-8-sig') as f:
          writer = csv.writer(f)
          #轉化為列表 儲存
          writer.writerow(list(value))
      else:
        conn = pymysql.connect(host='127.0.0.1',user='root',passwd='',db='',port=3306,charset='utf8')
        cursor = conn.cursor()
        sql = ''
        cursor.execute(sql)
        conn.commit()
        cursor.close()
        conn.close()
  #公有物件方法 執行所有爬蟲操作
  def my_run(self,parser_type=1,save_type=1):
    my_url = self.__my_url()
    for value in my_url:
      result = self.__my_request(value,parser_type)
      self.__my_save(result,save_type)

呼叫爬蟲類實現資料獲取

if __name__ == '__main__':
  #例項化建立物件
  dd = DDSpider('python',0)
  #引數 解析方式 my_run(parser_type,save_type)
  # parser_type 1 利用正則 2 bs4 3 xpath 
  #儲存方式 save_type 1 txt 2 csv 3 mysql
  dd.my_run(2,1)

==總結一下: ==

1. 總體感覺正則表示式更簡便一些,程式碼也會更簡便,但是正則部分相對複雜和困難
2. bs4和xpath 需要對html程式碼有一定了解,取每條資料多個值時相對較繁瑣

更多關於Python相關內容可檢視本站專題:《Python Socket程式設計技巧總結》、《Python正則表示式用法總結》、《Python資料結構與演算法教程》、《Python函式使用技巧總結》、《Python字串操作技巧彙總》、《Python入門與進階經典教程》及《Python檔案與目錄操作技巧彙總》

希望本文所述對大家Python程式設計有所幫助。