Python爬虫不会?戳一下,小编一步步教你写一个简单的爬虫
寫在前面
網(wǎng)絡(luò)爬蟲又稱網(wǎng)絡(luò)蜘蛛,是指按照某種規(guī)則在網(wǎng)絡(luò)上爬取所需內(nèi)容的腳本程序。眾所周知,每個網(wǎng)頁通常包含其他網(wǎng)頁的入口,網(wǎng)絡(luò)爬蟲則通過一個網(wǎng)址依次進(jìn)入其他網(wǎng)址獲取所需內(nèi)容。
優(yōu)先申明:我們使用的python編譯環(huán)境為PyCharm
正文
一、首先一個網(wǎng)絡(luò)爬蟲的組成結(jié)構(gòu):
爬蟲調(diào)度程序(程序的入口,用于啟動整個程序)
url管理器(用于管理未爬取得url及已經(jīng)爬取過的url)
網(wǎng)頁下載器(用于下載網(wǎng)頁內(nèi)容用于分析)
網(wǎng)頁解析器(用于解析下載的網(wǎng)頁,獲取新的url和所需內(nèi)容)
網(wǎng)頁輸出器(用于把獲取到的內(nèi)容以文件的形式輸出)
二、編寫網(wǎng)絡(luò)爬蟲
(1)準(zhǔn)備所需庫
我們需要準(zhǔn)備一款名為BeautifulSoup(網(wǎng)頁解析)的開源庫,用于對下載的網(wǎng)頁進(jìn)行解析,我們是用的是PyCharm編譯環(huán)境所以可以直接下載該開源庫。
步驟如下:
選擇File->Settings
打開Project:PythonProject下的Project interpreter
點擊加號添加新的庫
輸入bs4選擇bs4點擊Install Packge進(jìn)行下載
(2)編寫爬蟲調(diào)度程序
這里的bike_spider是項目名稱引入的四個類分別對應(yīng)下面的四段代碼url管理器,url下載器,url解析器,url輸出器。
''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助, 群里還有不錯的視頻學(xué)習(xí)教程和PDF電子書! ''' # 爬蟲調(diào)度程序from bike_spider import url_manager, html_downloader, html_parser, html_outputer# 爬蟲初始化class SpiderMain(object):def __init__(self):self.urls = url_manager.UrlManager()self.downloader = html_downloader.HtmlDownloader()self.parser = html_parser.HtmlParser()self.outputer = html_outputer.HtmlOutputer()def craw(self, my_root_url):count = 1self.urls.add_new_url(my_root_url)while self.urls.has_new_url():try:new_url = self.urls.get_new_url()print("craw %d : %s" % (count, new_url))# 下載網(wǎng)頁html_cont = self.downloader.download(new_url)# 解析網(wǎng)頁new_urls, new_data = self.parser.parse(new_url, html_cont)self.urls.add_new_urls(new_urls)# 網(wǎng)頁輸出器收集數(shù)據(jù)self.outputer.collect_data(new_data)if count == 10:breakcount += 1except:print("craw failed")self.outputer.output_html()if __name__ == "__main__":root_url = "http://baike.baidu.com/item/Python/407313"obj_spider = SpiderMain()obj_spider.craw(root_url)(3)編寫url管理器
我們把已經(jīng)爬取過的url和未爬取的url分開存放以便我們不會重復(fù)爬取某些已經(jīng)爬取過的網(wǎng)頁。
''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助, 群里還有不錯的視頻學(xué)習(xí)教程和PDF電子書! ''' # url管理器class UrlManager(object):def __init__(self):self.new_urls = set()self.old_urls = set()def add_new_url(self, url):if url is None:returnif url not in self.new_urls and url not in self.old_urls:self.new_urls.add(url)def add_new_urls(self, urls):if urls is None or len(urls) == 0:returnfor url in urls:self.new_urls.add(url)def get_new_url(self):# pop方法會幫我們獲取一個url并且移除它new_url = self.new_urls.pop()self.old_urls.add(new_url)return new_urldef has_new_url(self):return len(self.new_urls) != 0(4)編寫網(wǎng)頁下載器
通過網(wǎng)絡(luò)請求來下載頁面
# 網(wǎng)頁下載器import urllib.requestclass HtmlDownloader(object):def download(self, url):if url is None:return Noneresponse = urllib.request.urlopen(url)# code不為200則請求失敗if response.getcode() != 200:return Nonereturn response.read()(5)編寫網(wǎng)頁解析器
對網(wǎng)頁進(jìn)行解析時我們需要知道我們要查詢的內(nèi)容都有哪些特征,我們可以打開一個網(wǎng)頁點擊右鍵審查元素來了解我們所查內(nèi)容的共同之處。
''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助, 群里還有不錯的視頻學(xué)習(xí)教程和PDF電子書! ''' # 網(wǎng)頁解析器import refrom bs4 import BeautifulSoupfrom urllib.parse import urljoinclass HtmlParser(object):def parse(self, page_url, html_cont):if page_url is None or html_cont is None:returnsoup = BeautifulSoup(html_cont, "html.parser", from_encoding="utf-8")new_urls = self._get_new_urls(page_url, soup)new_data = self._get_new_data(page_url, soup)return new_urls, new_datadef _get_new_data(self, page_url, soup):res_data = {"url": page_url}# 獲取標(biāo)題title_node = soup.find("dd", class_="lemmaWgt-lemmaTitle-title").find("h1")res_data["title"] = title_node.get_text()summary_node = soup.find("div", class_="lemma-summary")res_data["summary"] = summary_node.get_text()return res_datadef _get_new_urls(self, page_url, soup):new_urls = set()# 查找出所有符合下列條件的urllinks = soup.find_all("a", href=re.compile(r"/item/"))for link in links:new_url = link['href']# 獲取到的url不完整,學(xué)要拼接new_full_url = urljoin(page_url, new_url)new_urls.add(new_full_url)return new_urls(6)編寫網(wǎng)頁輸出器
輸出的格式有很多種,我們選擇以html的形式輸出,這樣我們可以的到一個html頁面。
# 網(wǎng)頁輸出器class HtmlOutputer(object):def __init__(self):self.datas = []def collect_data(self, data):if data is None:returnself.datas.append(data)# 我們以html表格形式進(jìn)行輸出def output_html(self):fout = open("output.html", "w", encoding='utf-8')fout.write("<html>")fout.write("<meta charset='utf-8'>")fout.write("<body>")# 以表格輸出fout.write("<table>")for data in self.datas:# 一行fout.write("<tr>")# 每個單元行的內(nèi)容fout.write("<td>%s</td>" % data["url"])fout.write("<td>%s</td>" % data["title"])fout.write("<td>%s</td>" % data["summary"])fout.write("</tr>")fout.write("</table>")fout.write("</body>")fout.write("</html>")# 輸出完畢后一定要關(guān)閉輸出器fout.close()寫在最后
對于爬蟲的學(xué)習(xí),小編建議大家還是多動手敲代碼,這樣不僅可以更好的理解,而且在敲代碼的過程中,遇到BUG時可以加深自己對于代碼的理解!
總結(jié)
以上是生活随笔為你收集整理的Python爬虫不会?戳一下,小编一步步教你写一个简单的爬虫的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 11道Python最基本的面试题
- 下一篇: 用 Python 快速实现 HTTP 和