Python+PhantomJS+selenium+BeautifulSoup實現簡易網絡爬蟲

Python+PhantomJS+selenium+BeautifulSoup實現簡易網絡爬蟲

簡易網絡小爬蟲,目標站:www.toutiao.com/python

已實現的功能

日期 功能
2017.08.12 可獲取首頁輪播圖數據並保存到本地數據庫
2017.08.16 可獲取首頁新聞列表每一項的所有數據(做者頭像除外)並保存到本地數據庫
僅供學習使用,若有侵權,敬請原諒。<(▰˘◡˘▰)>

Github地址: github.com/LalaTeam/Py…git

介紹

PhantomJS+selenium能夠說是...無敵的...github

一一介紹一下:web

PhantomJS: 實質上就是一個沒有界面的瀏覽器,最主要的功能是可以讀取js加載的頁面。sql

selenium: 瀏覽器自動化測試框架.可以模擬用戶的一些行爲操做,好比填寫指定輸入框,下拉操做等。數據庫

BeautifulSoup: 它是python的一個庫,最主要的功能是從網頁抓取數據。配合lxml解析,快速獲取指定標籤。瀏覽器

設計

基本思路:網絡

  • 利用PhantomJS模擬請求url
  • 拿到網頁源碼,解析xml
  • 獲取指定標籤
  • 根據標籤拿到須要的屬性值
  • 存入本地數據庫

網站分析

首先看一下咱們能要拿的數據框架

首頁有一個輪播圖和一個新聞列表svg

輪播圖包括圖片和文字標題

新聞列表包括圖片,標題,時間,分類,做者暱稱,評論數等等

打開瀏覽器開發者模式,分析一下標籤內容,

發現每一個標籤都帶有一個相似key的東西做爲惟一標識,

截取a標籤的href屬性group後面的一串數字做爲惟一標識,

點擊每一條新聞,發現新聞詳情的Url是頭條首頁Url+這個惟一標識,

新聞詳情url暫時不獲取,這裏只是先獲取首頁數據.

再分析一下,

每一類標籤都是相同的標籤名而且有相同的class,這樣就好辦了許多,只須要找到這一堆相同class的標籤,再遍歷獲取裏面的屬性值就能夠了.

想到這裏,基本就能夠開工了,

但實際上仍是有一個問題,

就是新聞列表不是一次性加載出來的,而且新聞的圖片是懶加載的,怎麼辦?

思前想後,仍是利用PhantomJS去滾動頁面,

因爲圖片是懶加載,因此必須滾動一遍到底部停留3秒才能夠拿到圖片URL 不然是圖片拿到的是svg+xml的Base64,

一直獲取到新聞時間爲一天前就中止獲取,

可是這樣仍是會獲取到有重複的新聞,

因此,仍是利用它自帶的key去判斷是否已存在,不存在則存入數據庫.

Perfect~

開工

driver = webdriver.PhantomJS()
driver.get(web_url)
# driver.page_source:網頁源碼
# 利用lxml解析源碼拿到標籤
# 找到指定的一類標籤
item_tags = BeautifulSoup(driver.page_source, 'lxml')
                                           .find_all('div', class_='bui-box single-mode')複製代碼

獲取每一類數據的標籤

for itemTag in item_tags:
            # key
            k = itemTag.find('div', class_='bui-left single-mode-lbox')
                                                           .a['href'].split('/')[2]
            # 圖片
            u = itemTag.find('div', class_='bui-left single-mode-lbox').a.img['src']
            # 時間
            t = itemTag.find('div', class_='single-mode-rbox')
                                      .find('span', class_='footer-bar-action').text
            # 標題
            title = itemTag.find('div', class_='title-box').a.text
            # 分類
            type = itemTag.find('div', class_='bui-left footer-bar-left').a.text
            # 做者頭像
            # head = itemTag.find('div', class_='single-mode-rbox')
            # .find('a', class_='footer-bar-action media-avatar')
            # 做者暱稱
            name = itemTag.find('div', class_='bui-left footer-bar-left')
                                     .find_all('a', class_='footer-bar-action source')
            na = "" if len(name) == 0 else name[0].text
            # 評論數
            num = itemTag.find('div', class_='bui-left footer-bar-left')
                                      .find_all('a',class_='footer-bar-action source')複製代碼

數據庫判斷插入或更新

@staticmethod
def isExistList(self, list):
    try:
            with connection.cursor() as cursor:
                for item in list:
                    key = item[2]
                    cursor.execute(list_select_sql, (key))
                    result = cursor.fetchone()
                    if result is None:
                        self.db_operate(list_insert_sql, item)
                    else:
                        temp = (item[0], item[1], item[5], item[8], item[2])
                        self.db_operate(list_update_sql, temp)
    finally:
            # connection.close()
            print('isExistList finally')複製代碼

滾動到底部的三種方式

# 滾動到底部三種方式
# 一、driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# 二、actions = ActionChains(driver)
# actions.move_to_element(e).perform()
elems = driver.find_elements_by_class_name("lazy-load-img")
driver.execute_script("arguments[0].scrollIntoView();", elems[len(elems) - 1])
# 停留三秒
time.sleep(3)複製代碼

各類SQL語句

home_insert_sql = "INSERT INTO `tt_home_page` (`content`, `pic_url`,`click_key`,`create_time`,`type`) VALUES (%s,%s,%s,%s,%s)"
home_select_sql = "SELECT `*` FROM `tt_home_page` WHERE `click_key`=%s"
home_update_sql = "UPDATE tt_home_page SET content = %s, pic_url = %s WHERE click_key = %s"

list_insert_sql = "INSERT INTO `tt_home_list` (`content`, `pic_url`,`click_key`,`create_time`,`type`,`web_time`,`author_name`,`author_head`,`comment_num`) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)"
list_select_sql = "SELECT `*` FROM `tt_home_list` WHERE `click_key`=%s"
list_update_sql = "UPDATE tt_home_list SET content = %s, pic_url = %s, web_time = %s, comment_num = %s WHERE click_key = %s"複製代碼

獲取到的數據

  • 首頁列表數據

  • 首頁輪播數據

以上一個簡單爬蟲就完成了,頗有意思~

具體項目可看Github,歡迎Star~

相關文章
相關標籤/搜索