爬取《The Hitchhiker』s Guide to Python!》python進階書並製成pdf
來自專欄一起學爬蟲7 人贊了文章
這是日常學python的第15篇原創文章
前幾篇文章我們學習了requests庫和正則,還有個urllib庫,我上篇文章也用了requests庫來教大家去爬那些返回json格式的網頁,挺好玩的。有讀者讓我來個正則的,所以我今天就來個正則+requests來進行爬取。
今天原來是想爬小說的,但想到我不怎麼看小說,讀者也是都喜歡學習的,對吧?嘻嘻!所以我來爬個與python相關的內容,恰好前幾天我又看到別人推薦的一本python進階書,這本書的作者是我們的python大神kennethreitz徵集各路愛好python的人所寫的,下面是地址:
中文版:http://pythonguidecn.readthedocs.io/zh/latest/
英文版:http://docs.python-guide.org/en/latest/
這本書適合於一切有python的學習者,不管你是初入python的小白,還是熟練使用python的老手,都適用。但是不看也沒有影響你學習爬蟲哈,這個只是說些python的奇淫技巧。
由於這本書在網上只有英語的電子版,可我英語渣渣,所以爬個中文版的網頁然後把他弄成電子版。
若想直接獲取該書電子版,可以在公眾號「日常學python」後台回復『進階』直接獲取。
本篇文章用到的工具如下:
- requests庫
- 正則表達式
- Sigil:將html網頁轉成epub電子書
- epub轉pdf:http://cn.epubee.com/epub轉pdf.html
好了,下面詳細分析:
1分析網站內容
可以看到首頁中有整本書的內容鏈接,所以可以直接爬首頁獲取整本書的鏈接。
熟練地按下f12查看網頁請求,非常容易找到這個
請求網站為:http://pythonguidecn.readthedocs.io/zh/latest/
請求方式為get,狀態碼為200,而且返回的是html元素,所以我們可以用正則來匹配所需要的內容。
那看看我們的匹配內容所在的地方
可以看到這個內容的地址和內容標題都在這個a標籤上,所以正則很容易,如下:
toctree-l1.?reference internal" href="([^"]?)">(.?)</a>
不知道你的正則學得怎樣了,這裡還是簡單說下:
- .:這個是概括字符集,為匹配除換行符以外的任意字元
- :這個是數量詞,匹配的次數為0次以上
- ?:加了這個問號表示非貪婪,一般默認為貪婪
- [^"]:這個表示不匹配雙引號,挺好用的
實在不記得的可以看看我這篇文章,這裡不詳細說了,不記得就點開爬蟲必學知識之正則表達式下篇看看
這裡需要注意的是:在這裡獲取的網址列表裡面有個內容的導航,如下:
所有我們在匹配完之後還需要再將這些帶#號的網址給過濾掉。
接下來的就是獲取每個網頁的內容
可以看到內容都在這個div標籤內,所以和上面一樣,用正則就可以獲取了。
ps: 其實這裡用BeautifulSoup更好用,我會在後面文章中講到哈!
匹配內容的正則為:
section".?(<h1>.?)<div class="sphinxsidebar
因為我的那個工具是把這些內容的html下載下來就可以了,所以接下來不需要清洗裡面的html元素。
內容分析完畢,接下來的就容易了,就是用個循環把遍歷所有文章,然後就利用正則把他爬下來就可以了。
2實操部分
import re, requestsclass Spider(object): def init(self, headers, url): self.headers = headers self.url = url def gethrefs(self): 獲取書本的所有鏈接 response = requests.get(self.url, self.headers) if response.statuscode == 200: response.encoding = utf-8 hrefs = re.findall(toctree-l1.?reference internal" href="([^"]?)">(.?)</a>, response.text, re.S) return hrefs else: print(訪問書本內容失敗,狀態碼為, response.status_code) def get_page(self, url): 獲取首頁 response = requests.get(url, self.headers) response.encoding = utf-8 content = re.findall(section".?(<h1>.?)<div class="sphinxsidebar, response.text, re.S) return content[0] def get_content(self, href): 獲取每個頁面的內容 if href: href = self.url + href response = requests.get(href, self.headers) response.encoding = utf-8 content = re.findall(section".?(<h1>.*?)<div class="sphinxsidebar, response.text, re.S) if content: return content[0] else: print(正則獲取失敗) else: print(獲取內容失敗) def run(self): 循環獲取整本書內容 self.num = 0 hrefs = self.gethrefs() content = self.getpage(self.url) with open(str(self.num)+Python最佳實踐指南.html, w, encoding=utf-8) as f: f.write(content) print(寫入目錄成功) for href, title in hrefs: if "#" in href: continue self.num += 1 content = self.getcontent(href) with open(str(self.num)+title+.html, w, encoding=utf-8) as f: f.write(content) print(下載第+str(self.num)+章成功) print(下載完畢)def main(): url = http://pythonguidecn.readthedocs.io/zh/latest/ headers = {User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36} spider = Spider(headers, url) spider.run()if name == main: main()
點擊運行,感覺美滋滋,可惜啊,代碼總是愛玩弄你,趕緊報了個錯:
project/newspaper/spider.py", line 52, in run with open(str(self.num)+title+.html, w, encoding=utf-8) as f:FileNotFoundError: [Errno 2] No such file or directory: 38與C/C++庫交互.html
一眼看下去,還挺鬱悶的,我沒有打開文件的,都是在寫文件,為什麼報了這個錯?仔細一看報錯內容,這個名字有問題啊,你看
38與C/C++庫交互.html
這個在window系統是以為你在 38與C 的 C++庫交互.html 下的,怪不得會報錯,所以,我在這裡加了這個代碼把/給替換掉
3.把內容整成pdf
點擊Sigil 的 + 號把剛才下載的內容導入
生成目錄
添加書名作者
添加封面:點擊左上角的 工具 -> 添加封面 即可
點擊保存即可完成
轉pdf:http://cn.epubee.com/epub轉pdf.html
這個很容易就不說了。
結語
好了,文章內容就這麼多,下個文章就是學習新內容了。期待ing。
上述文章如有錯誤歡迎在留言區指出,如果這篇文章對你有用,點個贊,轉個發如何?
MORE延伸閱讀
??老司機帶你用python來爬取妹子圖
?? python爬蟲常用庫之requests詳解
?? 爬蟲必學知識之正則表達式下篇
http://weixin.qq.com/r/FSgRCa7EhPP7repq930H (二維碼自動識別)
推薦閱讀:
※python爬蟲爬取QQ說說並且生成詞雲圖,回憶滿滿!
※【爬蟲】爬取網易雲音樂評論2
※代理IP設置
※python爬取搜狗熱搜榜