Python写爬虫只需三步
文章目錄
- 一:爬蟲基本原理
- 爬蟲的自動化的操作流程(靈魂所在)
- 二. 爬蟲基本操作
- 1.發送請求
- 1.1 demo:
- 1.2 如何查看自己user-agent?
- 2.提取信息
- 2.1 正則表達式常用規則
- 2.2 正則表達式常用方法
- 2.3 解析庫介紹1:Beautiful Soup
- 2.4 解析庫介紹2:PyQuery
- 3.數據存儲
- 3.1 JSON形式保存
- 3.2 CSV形式保存
- 3.2 關系型數據庫MySQL保存
- 3.3非關系型數據庫MonogoDB保存
- 三.爬取貓眼電影前100
- 1.源碼
- 2.結果
一:爬蟲基本原理
爬蟲就是獲取網頁并提取和保存信息的自動化程序
如果把互聯網比喻為一張大網,那么每個網頁就是這張大網的一個節點,網頁與網頁之間的鏈接就相當于節點之間的連線,爬蟲每到一個節點就獲取他的信息,然后通過連線爬到另一個節點,這樣整個網的所有節點的數據就都可以被爬取下來了。
爬蟲的自動化的操作流程(靈魂所在)
在提取信息的過程中,可能經常會用到正則表達式獲取信息
二. 爬蟲基本操作
1.發送請求
使用requests庫進行發送請求的操作,簡單易上手
文檔連接如下:
中文文檔
官網中文版
1.1 demo:
import requestsheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)\Chrome/80.0.3987.106 Safari/537.36'}r = requests.get('http://maoyan.com/board/4', headers=headers)if r.status_code == 200:print(r.text)很多網站如果我們不提供user-agent的話是不讓爬的,so
1.2 如何查看自己user-agent?
Chrome:在瀏覽器的搜索框中輸入about:version即可
其他任何瀏覽器運行這段腳本就行了:
(復制下面代碼到新建的空html文件中,選擇你要的瀏覽器運行)
2.提取信息
發送完請求并且成功獲取到了網頁源碼后,需要提取我們需要的信息,正則表達式是非常常見的方法
2.1 正則表達式常用規則
| \w | 匹配字母、數字、下劃線 |
| \W | 匹配不是字母、數字、下劃線的字符 |
| \s | 匹配任意空白字符,等價于 [\t\n\r\f] |
| \S | 匹配任意非空白字符 |
| \d | 匹配任意數字、等價于 [0-9] |
| \D | 匹配任意非數字的字符 |
| \A | 匹配字符串開頭 |
| \Z | 匹配字符串結尾,如果存在換行,只匹配到換行前的結束字符串 |
| \z | 匹配字符串結尾,如果存在換行,同時還會匹配換行符 |
| \G | 匹配最后匹配完成的位置 |
| \n | 匹配一個換行符 |
| \t | 匹配一個制表符 |
| ^ | 匹配一行字符串的開頭 |
| $ | 匹配一行字符串的結尾 |
| . | 匹配任意字符,除了換行符,當re.DOTALL標記被指定時,則可以匹配包括換行符的任意字符 |
| [ … ] | 用來表示一組字符,單獨列出,比如[abc]匹配a、b或c |
| [ ^… ] | 匹配不在[]中的字符,比如[ ^abc ]則匹配a,b,c以外的字符 |
| * | 匹配0或多個表達式,貪婪型 |
| + | 匹配1個或多個表達式,貪婪型 |
| ? | 陪陪0個或1個表達式,非貪婪型 |
| {n} | 精確匹配n個前面的表達式,非貪婪型 |
| {n,m} | 匹配n到m次前面的表達式,貪婪型 |
| a|b | 匹配a或b |
| () | 匹配括號內的表達式,表示一個組 |
2.2 正則表達式常用方法
- compile()
- match()
- search()
- findall()
- sub()
每次根據源碼編寫我們的正則表達式模板就顯得很繁瑣,不夠優美。那么一套用來解析源碼輕而易舉獲取我們所需信息的工具就很有必要了。
2.3 解析庫介紹1:Beautiful Soup
Beautiful Soup 是一個可以從HTML或XML文件中提取數據的Python庫.它能夠通過你喜歡的轉換器實現慣用的文檔導航,查找,修改文檔的方式.Beautiful Soup將復雜HTML文檔轉換成一個復雜的樹形結構,每個節點都是Python對象,所有對象可以歸納為4種: Tag , NavigableString , BeautifulSoup , Comment.
船新包裝,船新體驗
官方中文文檔
Beautiful Soup在解析時實際上會依賴解析器:
根據需要選擇
| Python標準庫 | BeautifulSoup(markup, "html.parser") | Python的內置標準庫,執行速度適中,文檔容錯能力強 | Python 2.7.3 or 3.2.2)前 的版本中文檔容錯能力差 |
| lxml HTML 解析器 | BeautifulSoup(markup, "lxml") | 速度快,文檔容錯能力強 | 需要安裝C語言庫 |
| lxml XML 解析器 | BeautifulSoup(markup, ["lxml-xml"]) BeautifulSoup(markup, "xml") | 速度快,唯一支持XML的解析器 | 需要安裝C語言庫 |
| html5lib | BeautifulSoup(markup, "html5lib") | 最好的容錯性,以瀏覽器的方式解析文檔,生成HTML5格式的文檔 | 速度慢,不依賴外部擴展 |
如果你覺得Beautiful Soup還是有些麻煩或者不習慣
2.4 解析庫介紹2:PyQuery
它與JQuery的語法非常相似,CSS選擇器對于寫過前端的朋友來說簡直不要太好用
輕松上手,縱享絲滑
官方文檔
初始化
from pyquery import PyQuery as pq- html字符串初始化
- URL初始化
- 文件初始化
CSS選擇器
doc = pq(html) doc('#container ul li') #獲取id=container節點下的li節點節點查找
- 子節點
find()、children() - 父節點
parent() - 兄弟節點
siblings()
遍歷
items()
信息獲取
- 屬性
attr() - 文本
text()、html()
具體用法詳情可以看官方文檔
3.數據存儲
#已獲取信息result with open("result.txt", 'a', encoding='utf-8') as f:f.write(result)這么做也能保存數據,但是不夠炫酷。
3.1 JSON形式保存
JSON全稱JavaScripte Object Notation(JavaScript的對象標記),它通過對象數組來表示數據,構造簡潔,結構化程度高,是一種輕量級的數據交換格式。
JavaScript中,用{}括起來的內容表示對象,與python中的字典寫法很像,其結構為{key0: value0,key1: value1 }
JavaScript中,用[]括起來的部分表示數組,與python中的列表寫法很像,其結構為['value0', 'value1']
綜上,JSON數據格式為:
[{"name": "Bob","age": "12"},{"name": "Tom","age": "11"} ]JSON的數據要用雙引號包圍,不能使用單引號,不然解析時會出問題
JSON解析的過程就是將字符串轉為JSON對象,反之亦然。
用load()和dumps()方法可以輕松實現數據轉換
JSON文本loads()→JSON對象JSON文本 \hspace2ex \underrightarrow{loads()} \hspace2ex JSON對象JSON文本loads()?JSON對象
JSON文本dumps()←JSON對象JSON文本 \hspace2ex \underleftarrow{dumps()} \hspace2ex JSON對象JSON文本dumps()?JSON對象
3.2 CSV形式保存
CSV,全稱為Comma-Separated Values,中文可以叫做逗號分隔值或字符分隔值,其文件以純文本的形式處理表格數據。
文件格式如下
num1, num2, num3 1,2,3 a,b,c寫csv文件:
import csvwith open('data.csv', 'w') as csvfile:filenames = ['id', 'name', 'age']writer = csv.DictWriter(csvfile, fieldnames=filenames)writer.writerow('id':'11001','name':'Bob', 'age': '10')writer.writerow('id':'11002','name':'Tim', 'age': '10')writer.writerow('id':'11003','name':'Mike', 'age': '10')或者:
import csvwith open('data.csv', 'w') as csvfile:writer = csv.Writer(csvfile)writer.writerow('id', 'name', 'age')writer.writerow('11001','Bob','10')writer.writerow('11002','Tim','10')writer.writerow('11003','Mike','10')效果是一樣的
讀csv文件:
import csvwith open('data.csv', w) as csvfile:reader = csv.reader(csvfile)for row in reader:print(row)3.2 關系型數據庫MySQL保存
關系型數據庫是基于數據模型之關系模型的一種數據庫,區別于層次數據庫和網狀數據庫。關系數據庫通過表來存儲數據,表的每一列稱為一個字段,對應一個域,表示實體的某一屬性,表的每一行稱為一條記錄,對應一個元組,是某一實體分量的集合。不同的表之間通過主鍵和外鍵進行關聯,多表關聯組成關系型數據庫。
有關python連接mysql以及CRUD操作:
import pymysql#連接數據庫 db = pymysql.connect(host='localhost',user='root',password='123456',port=3306,db='spider') cursor = db.cursor() #增 sql0 = 'INSERT INTO table(column0,column1,column2) values(%s, %s, %s)'#此類 #刪 sql1 = 'DELETE FROM table WHERE condition'#此類 #查 sql2 = 'SELECT * FROM table WHERE age >= 20'#此類 #改 sql3 = 'UPDATE table SET column = %s WHERE condition'#此類try:cursor.execute(sql)#或附加數據cursor.execut(sql, data)db.commit() except:db.rollback() db.close()會用sql查詢的,這個可以直接上手用
3.3非關系型數據庫MonogoDB保存
MongoDB是由C++語言編寫的非關系型數據庫,是一個基于分布式文件存儲訂單的開源數據庫系統,其內存儲存形式類似于JSON對象,他的字段值可以包含其他文檔,數組以及文檔數組,非常靈活。
官方文檔
內容不多,能很快掌握
三.爬取貓眼電影前100
采用Requests + PyQuery+JSON
1.源碼
import requests import json import re from pyquery import PyQuery as pqdef get_one_page(m_url):headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)\Chrome/80.0.3987.106 Safari/537.36'}r = requests.get(m_url, headers=headers)if r.status_code == 200:return r.textreturn Nonedef parser_one_page(m_html):#正則表達式模板"""patter = re.compile('<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?name.*?a.*?>(.*?)</a>''.*?star.*?>(.*?)</p>.*?releasetime.*?>(.*?)</p>.*?integer.*?>(.*?)</i>.*?''fraction.*?>(.*?)</i>.*?</dd>', re.S)items = re.findall(patter, m_html)"""#PyQuerydoc = pq(m_html)for item in doc.find('dd').items():yield {'index': item('i.board-index').text(),'image': item('img.board-img').attr('data-src'),'title': item('p.name').children('a').text(),'actor': item('p.star').text().strip()[3:] if len(item('p.star').text().strip()) > 3 else '','time': item('p.releasetime').text().strip()[5:] if len(item('p.releasetime').text().strip()) > 5 else '','score': item('p.score').children('i.integer').text().strip() +item('p.score').children('i.fraction').text().strip()}def write_to_file(content):with open('maoyan_result.txt', 'a', encoding='utf-8') as f:f.write(json.dumps(content, indent=2, ensure_ascii=False) + '\n')def run(offset):url = 'http://maoyan.com/board/4?offset=' + str(offset)html = get_one_page(url)for item in parser_one_page(html):write_to_file(item)if __name__ == '__main__':for i in range(10):run(offset=i*10)2.結果
參考資料:《Python3網絡爬蟲開發實踐》,Google
如果對您有幫助,點贊、收藏、關注! 😃
總結
以上是生活随笔為你收集整理的Python写爬虫只需三步的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 再来一次的C语言贪吃蛇小游戏(三)
- 下一篇: 你了解欧拉回路吗?(附Java实现代码)