大家好,我是安果!
之前有寫過 2 篇關(guān)于價(jià)值投資方面的文章
教你用 Python 快速獲取相關(guān)概念股,輔助價(jià)值投資!
教你用 Python 快速獲取行業(yè)板塊股,輔助價(jià)值投資!
量化交易有一個(gè)非常重要的指標(biāo) AR,它是通過固定公式計(jì)算出的,用于反映市場買賣人氣的技術(shù)指標(biāo)
一般用在多支股票的對(duì)比,通過 AR 技術(shù)指標(biāo)能獲取相應(yīng)股票的熱門指數(shù),輔助我們進(jìn)行選擇
本篇文章將結(jié)合滾動(dòng)市盈率 PE 爬取熱門股票,篩選出適合投資的股票
目標(biāo)對(duì)象:
aHR0cHMlM0EvL2d1YmEuZWFzdG1vbmV5LmNvbS9yYW5rLw==
具體操作步驟如下
1-1 安裝依賴
# 安裝依賴
pip3 install selenium
pip3 install pandas
1-2 ChromeDriver 及打開首頁
根據(jù) Chrome 瀏覽器的版本號(hào)下載對(duì)應(yīng)版本的驅(qū)動(dòng),并放置到本地
http://chromedriver.storage.googleapis.com/index.html
然后使用 Selenium 打開目標(biāo)網(wǎng)頁
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
chrome_options = Options()
# 無頭模式運(yùn)行
chrome_options.add_argument('--headless')
s = Service(r"C:\work\chromedriver.exe")
browser = webdriver.Chrome(service=s, options=chrome_options)
browser.implicitly_wait(5)
@calc_run_time
def start():
url = '主頁地址'
browser.get(url)
browser.maximize_window(
1-3 爬取熱門股票列表數(shù)據(jù)
首先,利用顯式等待直到設(shè)定的頁面元素完全加載出來
然后,對(duì)頁面元素進(jìn)行分析,利用 Xpath 爬取熱門股票的名稱、價(jià)格、漲幅、URL、排名
最后,循環(huán)爬取每一頁的數(shù)據(jù)保存到一個(gè)列表中
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
def get_rank_list():
"""
獲取熱門股票列表數(shù)據(jù)
:return:
"""
datas = []
# 股票熱度排名
rank_no = 0
# 抓取所有數(shù)據(jù)
while True:
# 等待加載完成(顯示等待)
WebDriverWait(browser, 120, 0.5).until(
EC.presence_of_element_located((By.XPATH, '//*[@class="stock_tbody"]/tr'))
)
# 處理數(shù)據(jù)
tr_elements = browser.find_elements(By.XPATH, '//*[@class="stock_tbody"]/tr')
for tr_element in tr_elements:
name = tr_element.find_element(By.XPATH, './/div[@class="nametd_box"]/a').text
price = tr_element.find_element(By.XPATH, './/td[7]/div').text
up_rate = tr_element.find_element(By.XPATH, './/td[9]/div').text # 漲跌幅度
stock_home_url = tr_element.find_element(By.XPATH, './/td[4]//a').get_attribute("href")
rank_no = rank_no + 1
datas.append({
"name": name,
"price": price,
"up_rate": up_rate,
"stock_home_url": stock_home_url,
"rank_no": rank_no,
"pe": 0.0
})
# 點(diǎn)擊下一頁
try:
page_next = browser.find_element(By.XPATH, '//a[contains(text(), "下一頁")]')
except:
page_next = None
# 如果是最后一頁,就中斷
if page_next:
page_next.click()
else:
break
1-4 獲取個(gè)股 PE
根據(jù)上面獲取的個(gè)股 URL 爬取滾動(dòng)市盈率
需要注意的是,滾動(dòng)市盈率是鼠標(biāo) Hover 在上面 icon 處才會(huì)顯示,所以我們需要模擬鼠標(biāo)移動(dòng)到上面圖標(biāo)的位置
from selenium.webdriver.common.action_chains import ActionChains
def get_stock_pe(stock_home_url):
"""
獲取股票的動(dòng)態(tài)PE
:param stock_home_url:
:return:
"""
browser.get(stock_home_url)
browser.maximize_window()
# 等待加載完成
WebDriverWait(browser, 120, 0.5).until(
EC.presence_of_element_located((By.XPATH, '//div[@class="ssy"]//li[5]/span'))
)
# PE ICON
pe_element = browser.find_element(By.XPATH, '//td[@class="n"]/span[@class="title_help"]')
# 動(dòng)態(tài)PE
pe_dynamic = browser.find_element(By.XPATH, '//div[@class="brief_info_c"]//tr[1]/td[12]/span/span').text
# return float(pe)
# 移動(dòng)鼠標(biāo)位置到PE ICON處,展示滾動(dòng)PE
ActionChains(browser).move_to_element(pe_element).perform()
# 獲取滾動(dòng)市盈率
pe_roll = browser.find_element(By.XPATH, '//span[@class="title_help"]//div[@class="ssy"]//li[5]/span').text
# 異常處理
try:
pe_roll = float(pe_roll)
except:
pe_roll = 0.0
return pe_roll
...
# 獲取股票的滾動(dòng)PE,設(shè)置進(jìn)去
for item in datas:
item['pe'] = get_stock_pe(item.get("stock_home_url"))
# 隨機(jī)休眠
random_sleep()
...
另外,為了應(yīng)對(duì)反爬,這里使用 random 模塊內(nèi)置函數(shù)模擬隨機(jī)的休眠等待
import random
import time
def random_sleep(mu=1, sigma=0.4):
"""隨機(jī)睡眠
:param mu: 平均值
:param sigma: 標(biāo)準(zhǔn)差,決定波動(dòng)范圍
"""
secs = random.normalvariate(mu, sigma)
if secs <= 0:
secs = mu # 太小則重置為平均值
print("休眠時(shí)間:", secs)
time.sleep(secs)
1-5 數(shù)據(jù)清洗
然后利用 Pandas 對(duì)數(shù)據(jù)鍵值對(duì)進(jìn)行重命名,并通過 PE 值對(duì)數(shù)據(jù)進(jìn)行一次過濾
PS:這里過濾出滾動(dòng)市盈率大于 0 且小于 30 的股票
import pandas as pd
# 重命名
code = {"name": "名稱", "price": "價(jià)格", "up_rate": "漲跌幅", "stock_home_url": "URL", "rank_no": "排名",
"pe": "動(dòng)態(tài)PE"}
result = pd.DataFrame(datas).rename(columns=code)
# 數(shù)據(jù)轉(zhuǎn)換
# 將Series列字符串轉(zhuǎn)為Float數(shù)據(jù)類型
# result["動(dòng)態(tài)PE"] = result["動(dòng)態(tài)PE"].astype(float)
# 過濾出PE為正,且數(shù)據(jù)小于30的數(shù)據(jù)
result = result[(0 < result["動(dòng)態(tài)PE"]) & (result["動(dòng)態(tài)PE"] <= 30)]
1-6 排序、保存
接著,按 PE 列進(jìn)行升序排列,最后保存到 CSV 文件
import pandas as pd
...
# 按PE升序排列,并重新標(biāo)記索引
result = result.sort_values(by="動(dòng)態(tài)PE", ascending=True, ignore_index=True)
result.to_csv("熱門股票排名.csv")
...
最后打開 CSV 文件,發(fā)現(xiàn)股票名稱、排名、PE、價(jià)格等關(guān)鍵數(shù)據(jù)寫入到文件中了,這些數(shù)據(jù)可以輔助我們進(jìn)行量化投資
當(dāng)然,我們可以將爬蟲部署到服務(wù)器,并將數(shù)據(jù)寫入到數(shù)據(jù)庫,方便我們后期進(jìn)行數(shù)據(jù)分析及可視化
如果你對(duì)量化交易有自己的想法,歡迎在評(píng)論區(qū)交流!
聯(lián)系客服