十幾年來總結的最經典的專案,用來作為python爬蟲實踐教學!
一、前言
這篇文章之前是給新人培訓時用的,大家覺的挺好理解的,所以就分享出來,與大家一起學習。如果你學過一些python,想用它做些什麼又沒有方向,不妨試試完成下面幾個案例。
二、環境準備
安裝requests lxml beautifulsoup4 三個庫(下面程式碼均在python3.5環境下通過測試)
pip install requests lxml beautifulsoup4
三、幾個爬蟲小案例
-
獲取本機公網IP地址
-
利用百度搜索介面,編寫url採集器
-
自動下載搜狗桌布
-
自動填寫調查問卷
-
獲取公網代理IP,並判斷是否能用、延遲
3.1 獲取本機公網IP地址
利用公網上查詢IP的藉口,使用python的requests庫,自動獲取IP地址。
import requests r = requests.get("http://2017.ip138.com/ic.asp") r.encoding = r.apparent_encoding #使用requests的字元編碼智慧分析,避免中文亂碼 print(r.text) # 你還可以使用正則匹配re模組提取出IP import re print(re.findall("d{1,3}.d{1,3}.d{1,3}.d{1,3}",r.text))
3.2 利用百度搜索介面,編寫url採集器
這個案例中,我們要使用requests結合BeautifulSoup庫來完成任務。我們要在程式中設定User-Agent頭,繞過百度搜索引擎的反爬蟲機制(你可以試試不加User-Agent頭,看看能不能獲取到資料)。注意觀察百度搜索結構的URL連結規律,例如第一頁的url連結引數pn=0,第二頁的url連結引數pn=10…. 依次類推。這裡,我們使用css選擇器路徑提取資料。
import requests from bs4 import BeautifulSoup # 設定User-Agent頭,繞過百度搜索引擎的反爬蟲機制 headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0'} # 注意觀察百度搜索結構的URL連結規律,例如第一頁pn=0,第二頁pn=10.... 依次類推,下面的for迴圈搜尋前10頁結果 for i in range(0,100,10): bd_search = "https://www.baidu.com/s?wd=inurl:/dede/login.php?&pn=%s" % str(i) r = requests.get(bd_search,headers=headers) soup = BeautifulSoup(r.text,"lxml") # 下面的select使用了css選擇器路徑提取資料 url_list = soup.select(".t > a") for url in url_list: real_url = url["href"] r = requests.get(real_url) print(r.url)
編寫好程式後,我們使用關鍵詞inurl:/dede/login.php 來批量提取織夢cms的後臺地址,效果如下:
3.3 自動下載搜狗桌布
這個例子,我們將通過爬蟲來自動下載搜過桌布,程式中存放圖片的路徑改成你自己想要存放圖片的目錄路徑即可。還有一點,程式中我們用到了json庫,這是因為在觀察中,發現搜狗桌布的地址是以json格式存放,所以我們以json來解析這組資料。
import requests import json #下載圖片 url = "http://pic.sogou.com/pics/channel/getAllRecomPicByTag.jsp?category=%E5%A3%81%E7%BA%B8&tag=%E6%B8%B8%E6%88%8F&start=0&len=15&width=1366&height=768" r = requests.get(url) data = json.loads(r.text) for i in data["all_items"]: img_url = i["pic_url"] # 下面這行裡面的路徑改成你自己想要存放圖片的目錄路徑即可 with open("/home/evilk0/Desktop/img/%s" % img_url[-10:]+".jpg","wb") as f: r2 = requests.get(img_url) f.write(r2.content) print("下載完畢:",img_url)
3.4 自動填寫調查問卷
目標官網:https://www.wjx.cn
目標問卷:https://www.wjx.cn/jq/21581199.aspx
import requests import random url = "https://www.wjx.cn/joinnew/processjq.ashx?submittype=1&curID=21581199&t=1521463484600&starttime=2018%2F3%2F19%2020%3A44%3A30&rn=990598061.78751211" data = { "submitdata" : "1$%s}2$%s}3$%s}4$%s}5$%s}6$%s}7$%s}8$%s}9$%s}10$%s" } header = { "User-Agent" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko)", "Cookie": ".ASPXANONYMOUS=iBuvxgz20wEkAAAAZGY4MDE1MjctNWU4Ni00MDUwLTgwYjQtMjFhMmZhMDE2MTA3h_bb3gNw4XRPsyh-qPh4XW1mfJ41; spiderregkey=baidu.com%c2%a7%e7%9b%b4%e8%be%be%c2%a71; UM_distinctid=1623e28d4df22d-08d0140291e4d5-102c1709-100200-1623e28d4e1141; _umdata=535523100CBE37C329C8A3EEEEE289B573446F594297CC3BB3C355F09187F5ADCC492EBB07A9CC65CD43AD3E795C914CD57017EE3799E92F0E2762C963EF0912; WjxUser=UserName=17750277425&Type=1; LastCheckUpdateDate=1; LastCheckDesign=1; DeleteQCookie=1; _cnzz_CV4478442=%E7%94%A8%E6%88%B7%E7%89%88%E6%9C%AC%7C%E5%85%8D%E8%B4%B9%E7%89%88%7C1521461468568; jac21581199=78751211; CNZZDATA4478442=cnzz_eid%3D878068609-1521456533-https%253A%252F%252Fwww.baidu.com%252F%26ntime%3D1521461319; Hm_lvt_21be24c80829bd7a683b2c536fcf520b=1521461287,1521463471; Hm_lpvt_21be24c80829bd7a683b2c536fcf520b=1521463471", } for i in range(0,500): choice = ( random.randint(1, 2), random.randint(1, 4), random.randint(1, 3), random.randint(1, 4), random.randint(1, 3), random.randint(1, 3), random.randint(1, 3), random.randint(1, 3), random.randint(1, 3), random.randint(1, 3), ) data["submitdata"] = data["submitdata"] % choice r = requests.post(url = url,headers=header,data=data) print(r.text) data["submitdata"] = "1$%s}2$%s}3$%s}4$%s}5$%s}6$%s}7$%s}8$%s}9$%s}10$%s"
當我們使用同一個IP提交多個問卷時,會觸發目標的反爬蟲機制,伺服器會出現驗證碼。
我們可以使用X-Forwarded-For來偽造我們的IP,修改後程式碼如下:
import requests import random url = "https://www.wjx.cn/joinnew/processjq.ashx?submittype=1&curID=21581199&t=1521463484600&starttime=2018%2F3%2F19%2020%3A44%3A30&rn=990598061.78751211" data = { "submitdata" : "1$%s}2$%s}3$%s}4$%s}5$%s}6$%s}7$%s}8$%s}9$%s}10$%s" } header = { "User-Agent" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko)", "Cookie": ".ASPXANONYMOUS=iBuvxgz20wEkAAAAZGY4MDE1MjctNWU4Ni00MDUwLTgwYjQtMjFhMmZhMDE2MTA3h_bb3gNw4XRPsyh-qPh4XW1mfJ41; spiderregkey=baidu.com%c2%a7%e7%9b%b4%e8%be%be%c2%a71; UM_distinctid=1623e28d4df22d-08d0140291e4d5-102c1709-100200-1623e28d4e1141; _umdata=535523100CBE37C329C8A3EEEEE289B573446F594297CC3BB3C355F09187F5ADCC492EBB07A9CC65CD43AD3E795C914CD57017EE3799E92F0E2762C963EF0912; WjxUser=UserName=17750277425&Type=1; LastCheckUpdateDate=1; LastCheckDesign=1; DeleteQCookie=1; _cnzz_CV4478442=%E7%94%A8%E6%88%B7%E7%89%88%E6%9C%AC%7C%E5%85%8D%E8%B4%B9%E7%89%88%7C1521461468568; jac21581199=78751211; CNZZDATA4478442=cnzz_eid%3D878068609-1521456533-https%253A%252F%252Fwww.baidu.com%252F%26ntime%3D1521461319; Hm_lvt_21be24c80829bd7a683b2c536fcf520b=1521461287,1521463471; Hm_lpvt_21be24c80829bd7a683b2c536fcf520b=1521463471", "X-Forwarded-For" : "%s" } for i in range(0,500): choice = ( random.randint(1, 2), random.randint(1, 4), random.randint(1, 3), random.randint(1, 4), random.randint(1, 3), random.randint(1, 3), random.randint(1, 3), random.randint(1, 3), random.randint(1, 3), random.randint(1, 3), ) data["submitdata"] = data["submitdata"] % choice header["X-Forwarded-For"] = (str(random.randint(1,255))+".")+(str(random.randint(1,255))+".")+(str(random.randint(1,255))+".")+str(random.randint(1,255)) r = requests.post(url = url,headers=header,data=data) print(header["X-Forwarded-For"],r.text) data["submitdata"] = "1$%s}2$%s}3$%s}4$%s}5$%s}6$%s}7$%s}8$%s}9$%s}10$%s" header["X-Forwarded-For"] = "%s"
效果圖:
關於這篇文章,因為之前寫過,不贅述,感興趣直接看: 【如何通過Python實現自動填寫調查問卷】
3.5 獲取公網代理IP,並判斷是否能用、延遲時間
這一個例子中,我們想爬取 【西刺代理】上的代理IP,並驗證這些代理的存活性以及延遲時間。(你可以將爬取的代理IP新增進proxychain中,然後進行平常的滲透任務。)這裡,我直接呼叫了linux的系統命令ping -c 1 " + ip.string + " | awk 'NR==2{print}' - ,如果你想在Windows中執行這個程式,需要修改倒數第三行os.popen中的命令,改成Windows可以執行的即可。
from bs4 import BeautifulSoup import requests import os url = "http://www.xicidaili.com/nn/1" headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36'} r = requests.get(url=url,headers=headers) soup = BeautifulSoup(r.text,"lxml") server_address = soup.select(".odd > td:nth-of-type(4)") ip_list = soup.select(".odd > td:nth-of-type(2)") ports = soup.select(".odd > td:nth-of-type(3)") for server,ip in zip(server_address,ip_list): if len(server.contents) != 1: print(server.a.string.ljust(8),ip.string.ljust(20), end='') else: print("未知".ljust(8), ip.string.ljust(20), end='') delay_time = os.popen("ping -c 1 " + ip.string + " | awk 'NR==2{print}' -") delay_time = delay_time.read().split("time=")[-1].strip(" ") print("time = " + delay_time)
四、結語
當然,你還可以用python幹很多有趣的事情。