beautifulsoup+json抓取stackoverflow實戰

本文用beautifulsoup4庫抓取stackoverflow上python最新問題,存儲到json文件。前半部分通過抓取多個欄位練習beautifulsoup的使用,後半部分介紹json模塊

關於beautifulsoup的使用可以參考這篇文章BeautifulSoup全面總結

爬蟲代碼

import requests # 導入網頁請求庫from bs4 import BeautifulSoup # 導入網頁解析庫import reimport jsonclass Stack(object): def __init__(self): self.baseurl = https://stackoverflow.com # 用於與抓取的url拼接 self.starturl = https://stackoverflow.com/questions/tagged/python # 初始url def start_requests(self, url): # 發起請求 r = requests.get(url) return r.content def parse(self, text): # 解析網頁 soup = BeautifulSoup(text, html.parser) divs = soup.find_all(div, class_ = question-summary) for div in divs: # 一些中間變數 gold = div.find(span, title = re.compile(gold)) silver = div.find(span, title = re.compile(silver)) bronze = div.find(span, title = re.compile(bronze)) tags = div.find(div, class_ = summary).find_all(div)[1].find_all(a) # 用生成器輸出字典 yield { # 這部分每一條都有代表性 title: div.h3.a.text, url: self.baseurl + div.h3.a.get(href), answer: div.find(div, class_ = re.compile(status)).strong.text, view: div.find(div, class_ = views ).text[: -7].strip(), gold: gold.find(span, class_ = badgecount).text if gold else 0, tagnames: [tag.text for tag in tags], # 下面的從知識的角度上講都和上面一樣 vote: div.find(span, class_ = vote-count-post ).strong.text, time: div.find(div, class_ = user-action-time).span.get(title), duration: div.find(div, class_ = user-action-time).span.text, username: div.find(div, class_ = user-details).a.text, userurl: self.baseurl + div.find(div, class_ = user-gravatar32).a.get(href), reputation: div.find(span, class_ = reputation-score).text, silver: silver.find(span, class_ = badgecount).text if silver else 0, bronze: bronze.find(span, class_ = badgecount).text if bronze else 0, tagurls: [self.baseurl + tag.get(href) for tag in tags] } # 啟動爬蟲 def start(self): text = self.start_requests(self.starturl) items = self.parse(text) s = json.dumps(list(items), indent = 4, ensure_ascii=False) with open(stackoverflow.json, w, encoding = utf-8) as f: f.write(s)stack = Stack()stack.start()

抓取結果如下圖所示

上面代碼的基礎已經在前面文章中講過,有問題可以參考下面文章

  • 爬蟲基本原理
  • beautifulsoup詳解
  • 類和生成器的使用

json模塊介紹

json是一個內置模塊,無需自己安裝,模塊主要就用兩個函數json.dumpsjson.loads

  • 前者可以把一個list dict的python對象變成樣子相同的字元串,這樣轉化一般用於存儲到json文件中,因為json文件的形式和list dict是一樣的,而存儲文件需要使用字元串(或者bytes)
  • 後者將list dict樣子的字元串轉化為python對象,如果讀取json文件,得到的就是這樣的字元串,通過這個轉化將其變成python可以處理的list dict

示例代碼展示如下

import jsona = [{name:Bob, age: 20}, {name: Mary, age: 18}]s = json.dumps(a)s # 一個字元串# [{"age": 20, "name": "Bob"}, {"age": 18, "name": "Mary"}]b = json.loads(s)b[0]# {age: 20, name: Bob}b[0].get(age)# 20

存儲到文件時,為了讓字元串展示更好看一些,還有編碼問題,一般加參數如下

存儲到文件

s = json.dumps(a, indent = 4, ensure_ascii=False)with open(a.json, w, encoding = utf-8) as f: f.write(s)

參數indent指定一些縮進,不然寫到文件里所有字元都堆在一起不方便看。

ensure_ascii則是存儲內容涉及中文時需要指定(上面抓取stackoverflow沒有中文,所以其實是不需要指定的,只是為了引出這個參數才這麼用)

從文件中讀取

with open(a.json, encoding = utf-8) as f: s = f.read()b = json.loads(s)

專欄信息

專欄主頁:python編程

專欄目錄:目錄

爬蟲目錄:爬蟲系列目錄

版本說明:軟體及包版本說明

推薦閱讀:

python爬取QQ音樂
出門旅行沒規劃?python抓取馬蜂窩自由行攻略!
愛奇藝人物信息scrapy-redis
四、BeautifulSoup庫
請求、響應和反爬蟲

TAG:Python | python爬蟲 | 網頁爬蟲 |