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.dumps
和json.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庫
※請求、響應和反爬蟲