Python 爬蟲
什么是爬蟲?
首先我們要了解,對於一個網站是有一個鏈接的。我們訪問一個網站除了使用瀏覽器之外,還可以在 Linux 中使用 curl
命令訪問
# 例如:訪問百度
curl https://www.baidu.com/
會返回一個HTML的文件(網頁的源碼)
HTML -- 超文本編輯語言,專門用於前端
當然這個源碼在網頁中也能看到
也就是說,瀏覽器可以將源碼解析成網頁給我們看,而 Linux 的 shell 命令行不行
那么爬蟲就是通過代碼來訪問 https://www.baidu.com
網頁地址,爬取它的源數據,然后對其源數據進行解析,然后拿到我們想要的結果
當然源數據的格式可能有多種情況,有可能是 json 也可能是 html
如果源數據為 json 格式的,那么就會好解析一點
下面我們在微博手機版的網頁中演示一下爬蟲的使用
爬蟲的使用
我們先進入瀏覽器的開發者工具,然后拿到微博評價數據的地址
然后通過使用爬蟲的工具拉取數據並解析
requests
python 中爬蟲的工具有很多
下面我們先看一個很基礎的爬蟲工具(requests)的使用
requests -- 需要先通過 pip 命令裝一下
pip install requests
如何判斷使用那種請求?
方式1:通過瀏覽器的地址欄可以直接訪問的(可以直接拿到數據的) -- get請求,拿不到就用 post請求
方式2:
import requests
import json
# get請求:通過瀏覽器地址欄發起的請求,get請求的請求參數在url后面
# post請求:請求的參數在body(請求體)中, 一般用於登錄上傳用戶名密碼的時候
# 請求的路徑(url)
# ?id=4750848993266460&mid=4750848993266460&max_id_type=0 -- ? 的后面都是參數
url = "https://m.weibo.cn/comments/hotflow?id=4750848993266460&mid=4750848993266460&max_id_type=0"
# 發起請求, 返回請求的結果
response = requests.get(url=url)
# 獲取服務器響應請求后返回的結果數據
# 我們可以在IDEA中將拿到的json數據格式化之后看一下(通過IDEA將數據格式化)
text = response.text
print(text)
# 將返回的數據轉換成json
json_loads = json.loads(text)
# 解析數據並將數據存起來
with open("com.txt", mode="w", encoding="utf-8") as f:
for data in json_loads["data"]["data"]:
# 評價的時間
created_at = data["created_at"]
# 評價的內容
text = data["text"]
# 點贊數
like_count = data["like_count"]
# 取出用戶
user = data["user"]
user_id = user["id"]
screen_name = user["screen_name"]
gender = user["gender"]
line = "%s\t%s\t%s\t%s\t%s\t%s" % (user_id, screen_name, gender, like_count, created_at, text)
# 保存數據
f.write(line)
f.write("\n")
print(line)
json 格式好解析,就是那種網頁格式的(使用瀏覽器地址欄訪問地址直接顯示網頁的)就不是很好解析了
網頁格式的就需要通過
xpath
來解析了,需要先通過 pip 安裝pip install lxml
遇到帶有反爬蟲機制的網頁,如果不加請求頭,則程序跑完之后,什么數據都拉不到
那么如何找這個請求頭呢?
還是一樣的,要到瀏覽器的開發者工具中找
如何找
.xpath()
中需要的參數呢?要到瀏覽器的開發者工具中找
import requests
from lxml import etree
# 請求頭
# 如果將上圖中處理好的請求頭中的全部內容放在這里,返回給我們的數據會亂碼
# 所以我們只保留最后一個 User-Agent -- 誤導網頁服務端以為我們這個不是一個代碼(爬蟲),而是個瀏覽器
# 但是如果 User-Agent 不行的話,就需要將請求頭中的全部內容一個一個的試一遍,直到找出返回正常數據的那個
# 有的時候需要 Cookie
head = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36"
}
# 請求頁面獲取網頁數據
url = "https://movie.douban.com/top250?start=%7Bpage%7D&filter="
response = requests.request(url=url, method="get", headers=head)
# 獲取響應的內容
text = response.text
# 解析html -- 使用 xpath
etree_html = etree.HTML(text)
# 獲取所有影片
# .xpath() 中需要傳入的參數上面說了怎么找
# // : 查詢所有的(xpath的語法)
# ./ : 查詢當前的(xpath的語法)
# [@class='hd'] -- @:表示引用變量,這里查詢的是 class='grid_view' ,而不是上面圖中所說的 class='hd'
# [@class='grid_view']/ -- 這里的 / 表示: class='grid_view' 里面(內層)的 li 標簽
items = etree_html.xpath("//ol[@class='grid_view']/li")
# 遍歷解析影片
# text() -- 拿到標簽內的內容
# strip() -- 去掉字符串前后的空格或者制表符
for item in items:
# 一層一層的取出想要的數據,並打印
name = item.xpath("./div/div/div/a/span/text()")[0]
com = item.xpath("./div/div/div/div/span/text()")
score = com[0]
com_num = com[1]
dy = item.xpath("./div/div/div/p/text()")
dy1 = dy[0].strip()
year = dy[1].strip()
print(name, score, com_num, dy1, year)