「docker實戰篇」python的docker- 多裝置端併發抓取抖
之前的文章搞過,抖音web端使用者資訊的抓取和抖音app端粉絲的抓取。一臺裝置抓取抖音粉絲資料實在是太慢了,這次我們們來演示下多模擬器同時爬取資訊。原始碼: (原始碼/「docker實戰篇」python的docker- 多裝置端併發抓取抖音粉絲資料(22))
複製之前的帶xponsed的模擬器
- 1.桌面有夜神模擬器多開
- 2.選擇中,點選複製,可能一下複製出來3個,我們們不需要那麼多刪除2個就可以了,你如果電腦足夠強大也可以複製多個,下面程式碼的思路是一樣的。
- 3.複製完成後,改下別名,方便區別
-
- 啟動2個模擬器。
多工抓取
按照常理一般的網際網路操作,如果要實現多工抓取基本都是使用容器化的來完成的,但是目前直接說docker有點尚早,不過這個系列肯定是要實現docker的多裝置抓取的,這裡先說說使用python多程式的方式來完成。
- 1.檢視夜神模擬器的埠,啟動cmd,輸入
adb devices
- 2.如果輸入adb devices沒有列表
在啟動夜神模擬器的時候adb還沒啟動。也就是夜神模擬器比adb先啟動,解決方案。
1.開啟工作管理員,檢視夜神模擬器的PID,可以透過點選狀態-選中PID
2.剛檢視到的PID
netstat -ano | findstr "452"
netstat -ano | findstr "16712"
3.夜神模擬器埠是有規律的,第一個模擬器埠是62001,第二個是62025,第三個62025+1,第4個62025+2
- 手動的命令方式連線裝置
adb connect 127.0.0.1:62025
5.appium【客戶端】需要設定udid,在appium裡面識別就是udid,因為之前是一臺裝置所以不需要指定udid,光指定deviceName就可以了。
- appium【服務端】需要設定bootstrapPort,服務端進行設定,裝置和appium通訊的埠。
7.appium的2臺的屬性設定
1.douyin1 port=4723 bootstrapPort=4724
2.douyin1 port=4725 bootstrapPort=4726
-
- 報錯解決方案
selenium.common.exceptions.WebDriverException: Message: An unknown server-side error occurred while processing the command. Original error: Failed to Dump Window Hierarchy
解決方案
在含有Emoji特殊符號的頁面中,爆出Failed to Dump Window Hierarchy
http://blog.csdn.net/soslinken/article/details/50126477
won’t be solved until the new android driver is completed. This is a known bug in uiautomator v1
此問題是uiautomator自身bug,換用Android5.1以上的系統
原始碼
#!/usr/bin/env python
import time
from appium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import multiprocessing
def get_size(driver):
x = driver.get_window_size()['width']
y = driver.get_window_size()['height']
return (x, y)
def handle_douyin(driver):
while True:
#定位搜尋框
if WebDriverWait(driver,60).until(lambda x:x.find_element_by_xpath("//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[2]/android.widget.EditText[1]")):
#獲取douyin_id進行搜尋
driver.find_element_by_xpath("//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[2]/android.widget.EditText[1]").send_keys('1860719705')
while driver.find_element_by_xpath("//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[2]/android.widget.EditText[1]").text != '1860719705':
driver.find_element_by_xpath("//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[2]/android.widget.EditText[1]").send_keys('1860719705')
time.sleep(0.1)
#點選搜尋
driver.find_element_by_xpath("//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.TextView[1]").click()
#點選使用者標籤
if WebDriverWait(driver,30).until(lambda x:x.find_element_by_xpath("//android.widget.TextView[@text='使用者']")):
driver.find_element_by_xpath("//android.widget.TextView[@text='使用者']").click()
#點選頭像
if WebDriverWait(driver,30).until(lambda x:x.find_element_by_xpath("//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[2]/android.view.View[1]/android.support.v7.widget.RecyclerView[1]/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[1]/android.widget.ImageView[1]")):
driver.find_element_by_xpath("//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[2]/android.view.View[1]/android.support.v7.widget.RecyclerView[1]/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[1]/android.widget.ImageView[1]").click()
#點選粉絲按鈕
if WebDriverWait(driver,30).until(lambda x:x.find_element_by_xpath("//android.widget.TextView[@text='粉絲']")):
driver.find_element_by_xpath("//android.widget.TextView[@text='粉絲']").click()
x1 = int(driver.get_window_size()['width']*0.5)
y1 = int(driver.get_window_size()['height']*0.75)
y2 = int(driver.get_window_size()['height']*0.25)
while True:
time.sleep(3)
if '沒有更多了' in driver.page_source:
break
elif 'TA還沒有粉絲' in driver.page_source:
break
else:
driver.swipe(x1,y1,x1,y2)
time.sleep(0.5)
#返回
driver.find_element_by_xpath("//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.RelativeLayout[1]/android.widget.FrameLayout[1]/android.widget.ImageView[1]").click()
#返回
driver.find_element_by_id("com.ss.android.ugc.aweme:id/jk").click()
#重新清空使用者id
driver.find_element_by_xpath("//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[2]/android.widget.EditText[1]").clear()
def handle_appium(device,port):
cap = {
"platformName": "Android",
"platformVersion": "4.4.2",
"deviceName": device,
"udid":device,
# 真機的
# "platformName": "Android",
# "platformVersion": "7.1.2",
# "deviceName": "10d4e4387d74",
"appPackage": "com.ss.android.ugc.aweme",
"appActivity": "com.ss.android.ugc.aweme.main.MainActivity",
"noReset": True,
"unicodeKeyboard": True,
"resetkeyboard": True
}
driver = webdriver.Remote(""+str(port)+"/wd/hub", cap)
try:
# 點選搜尋
print('點選搜尋')
if WebDriverWait(driver, 60).until(lambda x: x.find_element_by_xpath(
"//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.FrameLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.TabHost[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.view.View[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[2]/android.widget.FrameLayout[1]/android.widget.ImageView[1]")):
driver.find_element_by_xpath(
"//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.FrameLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.TabHost[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.view.View[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[2]/android.widget.FrameLayout[1]/android.widget.ImageView[1]").click()
except:
# [26,76][115,165]
driver.tap([(26, 76), (115, 165)], 500)
handle_douyin(driver)
if __name__ == '__main__':
m_list = []
#定義了2臺虛擬裝置,夜神模擬器
devices_list = ["127.0.0.1:62001","127.0.0.1:62025"]
for device in range(len(devices_list)):
port = 4723 + 2 * device
m_list.append(multiprocessing.Process(target=handle_appium,args=(devices_list[device],port,)))
for m1 in m_list:
m1.start()
for m2 in m_list:
m2.join()
啟動步驟
- 1.啟動2個appium
之前上邊已經提到過的埠(4723 4724 )(4725 4726)
- 2.啟動python程式碼,檢視效果
除錯測試程式碼次數太多了,douyin要求我登入,哈哈
偽裝爬蟲
剛出現的因為訪問冊數太多,douyin那邊識別了,這樣需要解決。透過代理的方式。
- 1.購買代理的ip,還是用我們們的老朋友【阿布雲】
- 2.登入【阿布雲】後,使用mitmdump的方式,設定阿布雲的代理
啟動cmd,輸入
mitmdump -s -p 8889 --mode upstream:HTTP隧道伺服器:埠 --upstream-auth 通行證照:通行秘鑰
mitmdump -s test.py -p 8889 --mode upstream: --upstream-auth HS821YO6BA7D6M8P:75021E5CF3AB82EE
- 3.模擬器的wifi也要設定對應的代理,之前說過在重複說下。
- 4.這樣就使用了代理的方式了。 所有請求就是代理的阿布雲了。
感謝老鐵的建議,以後的所有的系列的原始碼都是按照對應文章進行整理,原來的原始碼都是按照我的開發歷程的,這樣不適合中間參與進來的老鐵。
PS:除錯過程中,夜神模擬器,appium,python程式碼外掛沒有問題的話,程式在執行過程中出現的最多的問題還是xpath定位的問題,對於python的程式碼其實也是很好理解的。另外注意的文章中提到的要使用安卓5.1以上否則會因為頁面中含有Emoji特殊符號,爆出Failed to Dump Window Hierarchy。udid對於啟動多個模擬器的時候一定要進行設定。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4369/viewspace-2823064/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Docker-基礎篇Docker
- docker-安裝mongodbDockerMongoDB
- 「docker實戰篇」python的docker爬蟲技術-pythonDockerPython爬蟲
- Python爬蟲入門實戰之貓眼電影資料抓取(實戰篇)Python爬蟲
- [知識圖譜實戰篇] 一.資料抓取之Python3抓取JSON格式的電影實體PythonJSON
- docker-部署ElasticsearchDockerElasticsearch
- docker-部署kibanaDocker
- IDEA的Docker外掛實戰(Docker Image篇)IdeaDocker
- Python併發程式設計:提高網頁抓取效率實踐指南Python程式設計網頁
- IDEA的Docker外掛實戰(Docker-compose篇)IdeaDocker
- python:實戰篇Python
- Docker-容器使用Docker
- Docker-埠對映Docker
- Docker-第一課Docker
- Docker-第二課Docker
- IDEA的Docker外掛實戰(Dockerfile篇)IdeaDocker
- app 自動化測試 - 多裝置併發 -appium+pytest+ 多執行緒APP執行緒
- python多工抓取圖片Python
- Python爬蟲入門實戰之貓眼電影資料抓取(理論篇)Python爬蟲
- python基礎篇實戰Python
- docker-執行tomcat服務DockerTomcat
- docker-執行mysql服務DockerMySql
- docker-執行jenkins服務DockerJenkins
- 高併發後端設計-限流篇後端
- Docker小白到實戰之開篇概述Docker
- 利用mitmproxy實現抖音Cookie,裝置ID獲取(一)MITCookie
- 利用 mitmproxy 實現抖音 Cookie,裝置 ID 獲取 (一)MITCookie
- Postgres On Docker-窺探容器服務Docker
- 寫給前端工程師看的Docker教程-實戰篇前端工程師Docker
- kubernetes實戰篇之docker映象的打包與載入Docker
- Devops實戰(一)Docker的部署安裝以及Docker-Compose的使用devDocker
- 『中級篇』docker 使用bind Mounting實戰(36)Docker
- docker筆記45-客戶端對映ceph的rbd塊裝置Docker筆記客戶端
- docker筆記46-調整客戶端rbd塊裝置的大小Docker筆記客戶端
- Python《多執行緒併發爬蟲》Python執行緒爬蟲
- 3種方式實現python多執行緒併發處理Python執行緒
- Java高併發實戰,鎖的優化Java優化
- 【多執行緒與高併發 2】volatile 篇執行緒