Python爬蟲: 抓取One網頁上的每日一話和圖

278439392 8年前發布 | 28K 次閱讀 爬蟲 Python開發 Python

先說下需求

最近打算搜集點源數據,豐富下生活。嗯,最近看到One這個APP蠻好的。每天想你推送一張圖和一段話。很喜歡,簡單不復雜。而我想要把所有的句子都保存下來,又不想要每個頁面都去手動查看。因此,就有了Python。之前有點Python基礎,不過沒有深入。現在也沒有深入,用哪學哪吧。
網站的內容是這樣的,我想要圖片和這段話:

Python爬蟲: 抓取One網頁上的每日一話和圖

one

(一)一臺MAC電腦

(二)Python環境搭建(所有命令都是在terminal中輸入的)

  • 安裝homebrew
    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  • 安裝pip:這里我在terminal中輸入python -v,homebrew會自動幫你升級Python到2.7.11版本的。2.7.11版本里自帶了pip工具。
  • 安裝virtualenv:
    pip install virtualenv
  • 安裝request和beautifulsoup4:
    pip install requests beautifulsoup4
    參考這里

(三)分析

目的:找出三個內容所在的網頁標簽的位置,然后將它們提取出來。
網址:http://wufazhuce.com/one/1293
谷歌瀏覽器,右鍵->顯示網頁源代碼,然后就會彈出一堆HTML的東西了。這樣的:

Python爬蟲: 抓取One網頁上的每日一話和圖

網頁源文件

我想要的內容是這段話:“即使熱戀者的情感是錯覺、幻象或自戀行為,那又何妨,所謂人生就是一段不斷追求情愛的路程。 by 森山大道”。它在圖中畫紅線的地方。在<heda>標簽里的<meta>中,之后會用到,先往下看。
圖片的鏈接在哪里?顯然不在<head>中,往下找,然后就在<body>中,發現2處和圖片類似的鏈接。看圖

Python爬蟲: 抓取One網頁上的每日一話和圖

圖片鏈接地址

哪個鏈接是呢,點擊去,發現后一個鏈接,也就是67行這個img標簽的鏈接是。
然后,我還想知道哪一天的圖和文字。嗯,在回到<head>標簽里,很明顯有個<title>,里面的東西就是我們要的。這樣:
<title>VOL.1271 - 「ONE · 一個」</title>
 

(四)python編碼

想要抓取網頁上的內容,又不想自己去解析HTML,只好求助萬能的Google了。然后就找到了上面的鏈接。主要有兩個工具:request加載網頁,BeautifulSoup4解析HTML。

首先,抓取我們需要的哪三個內容:
進入python環境,然后敲入下面的代碼:

import requests
import bs4
response = requests.get('http://wufazhuce.com/one/1295')
soup = bs4.BeautifulSoup(response.text,"html.parser")

這樣,就可以將網頁信息存儲到soup中了。你可以敲入print soup試試。

接下來,我們獲得<title>VOL.1271 - 「ONE · 一個」</title>中的數字1271。怎么獲得呢,beautifulsoup4教程,提供了很好的方法,可以通過tag查找得到title的內容,然后截取字符串。termianl中輸入:

soup.title.string[3:7]

title是tag值,string是tag=title的字符串的值,也就是<title></title>之間的值,因為只有一個<title>tag,所以不用做判斷,直接獲取即可。

接下來,獲取一段話。

Python爬蟲: 抓取One網頁上的每日一話和圖

要截取的內容

這段話在<meta>中,而這里又有太多的<meta>了,怎么辦。這里要用到select方法了,它可以查找所有的<meta>,并返回一個列表。還要用到get方法,get可以獲得tag的屬性,如tag: <meta attr='abc'> tag.get('attr')值等于abc。這里我們要獲取的屬性是name,通過name='description'來區分。

for meta in soup.select('meta'):
    if meta.get('name') == 'description':
        print meta.get('content')

接下來,在兩個img標簽中,查找第2個img標簽標定的鏈接。這里通過find_all方法,它可以查找所有的符合要求的標簽。

soup.find_all('img')[1]['src']

這樣,我們就把所需要的信息找出來了。

Python爬蟲: 抓取One網頁上的每日一話和圖

終端示例

等等,之后我們還需要并發和保存文件。在此之前,先來看點別的。map函數有兩個參數,一個是函數,一個是序列。將序列的每個值,作為參數傳遞給函數,返回一個列表。參考這里
示例:

def echoInfo(num):
    return num

data = map(echoInfo, range(0,10)) print data</code></pre>

結果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
然后并發, python可以跨平臺使用,自身提供了多進程支持模塊:multiprocessing。而pool可以用來創建大量的子進程。
保存數據到文件。這里我們是吧數據解析后存儲到字典中,然后序列化為JSON模型,最后保存到文件的。
即:字典->JSON模型->存儲到文件。
字典->JSON模型,使用的是JSON模塊的json.dumps方法,該方法有一個參數,參數為字典,返回值是JSON字符串。
JSON模型->文件,使用的是json.load方法,可以將JSON存儲到文件中。

全部的代碼示例如下:

import argparse
import re
from multiprocessing import Pool
import requests
import bs4
import time
import json
import io

root_url = '

def get_url(num): return root_url + '/one/' + str(num)

def get_urls(num): urls = map(get_url, range(100,100+num)) return urls

def get_data(url): dataList = {} response = requests.get(url) if response.status_code != 200: return {'noValue': 'noValue'} soup = bs4.BeautifulSoup(response.text,"html.parser") dataList["index"] = soup.title.string[4:7] for meta in soup.select('meta'): if meta.get('name') == 'description': dataList["content"] = meta.get('content') dataList["imgUrl"] = soup.find_all('img')[1]['src'] return dataList

if name=='main': pool = Pool(4) dataList = [] urls = get_urls(10) start = time.time() dataList = pool.map(get_data, urls) end = time.time() print 'use: %.2f s' % (end - start) jsonData = json.dumps({'data':dataList}) with open('data.txt', 'w') as outfile: json.dump(jsonData, outfile)</code></pre>


 

文/取水(簡書)
原文鏈接:http://www.jianshu.com/p/c4f35dfe1a1f
 

 本文由用戶 278439392 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!