代碼review(一)
問題:獲取詳情頁鏈接的xpath陳述句id值是不固定的
解決:先獲取所有的id值,再將id值拼接到xpath陳述句中獲取詳情頁鏈接
總結:觀察html代碼,找到規律
# 獲取全域資訊
result = response.xpath('//*[@id="mp-pusher"]//table')
# 獲取所有drugname標簽
lists = result .xpath('.//tr/td/div/div/a/@href').extract()
# 存放drugname標簽,回圈處理drugname標簽字串
new_list = []
for i in lists:
new_i = i.replace('#', '')
new_list.append(new_i)
# 將處理好的標簽拼接xpath陳述句,提取所有url
for j in new_list:
url = f'.//*[@id="{j}"]/li/a/@href'
# 獲取所有詳情頁頁鏈接
link_list = result .xpath(url).extract()
# 拼接完整的詳情 頁鏈接
for k in link_list:
urls = str('**********') + k
yield scrapy.Request(
urls,
callback=self.new_parse
)
問題:爬取HMA需要點擊選項后獲取cookie,才能取到資料
解決:使用selenium模擬瀏覽器操作,獲取cookie
總結:通過selenium實作自動獲取cookie,在headers中添加’Cookie’: getCookie()
from selenium import webdriver
from selenium.webdriver.support.ui import Select # select類,下拉選單使用
def getCookie(self):
# 獲取谷歌驅動
driver = webdriver.Chrome()
# 訪問指定網站
driver.get("*****url*****")
# 選擇標簽
Select(driver.find_element_by_name('[0]Type')).select_by_value('RTE')
Select(driver.find_element_by_name('[0]Placeholder')).select_by_value('1')
time.sleep(2)
# 點擊提交
driver.find_element_by_xpath(r'//*[@id="searchform"]/div[4]/div/div/div/div/div/div/div/div/input[3]').click()
# 獲取cookie 回傳字典型別的串列
cookies = driver.get_cookies()
# 將driver獲取的字典型別的cookie提取name和value封裝成字串
cookie = []
for i in cookies:
cookie.append(i['name'] + '=' + i['value'])
# 獲取到資料后關閉瀏覽器
driver.close()
return ';'.join(cookie)
問題:使用selenium模擬瀏覽器被識別為爬蟲
解決:使用 Google 的Chrome Devtools-Protocol(Chrome 開發工具協議)簡稱CDP,selenium使用driver.execute_cdp_cmd,傳入需要呼叫的 CDP 命令和引數即可
總結:自動提前在網站自帶的所有js之前執行這個陳述句,隱藏window.navigator.webdriver
# 在driver.get前呼叫driver.execute_cdp_cmd
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
"""
})
問題:使用sqlalchemy連接兩個不同地址的資料庫,完成查詢和批量更新操作
解決:初始化兩個engine,創建兩個session完成操作
總結:將Table_1的id和Table_2查詢到的資料合并成一個字典,將字典存入mappings中,完成批量更新,有效提升更新效率
# 建立查詢條件,并列印資訊
# 查詢info資料作為Table_2的篩選條件,refe資料作為更新的索引
user_info = session1.query(Table_1.info,Table_1.refe_id).filter_by(refe_type="article",is_del=0).all()
mappings = []
count = 1
for i, j in user_info:
count += 1
if i.get("pmid"):
result = session2.query(Table_2.article_id).filter_by(article_pmid=i["pmid"]).first()
if result: # result為row型別
# 創建字典,'references_id'值作為索引,'article_id'值為要更新的資料
info = {'refe_id': j, 'article_id': result[0]}
else: # result為None
info = {'refe_id': j, 'article_id': result}
elif i.get("doi"):
result = session2.query(Table_2.article_id).filter_by(article_doi=i["article_doi"]).first()
if result:
info = {'refe_id': j, 'article_id': result[0]}
else:
info = {'refes_id': j, 'article_id': result}
else:
result = None
info = {'refe_id': j, 'article_id': result}
print(count, info)
mappings.append(info)
if count % 1000 == 0:
session1.bulk_update_mappings(Table_1, mappings)
session1.flush()
session1.commit()
mappings[:] = []
session1.bulk_update_mappings(Table_1, mappings)
session1.flush()
session1.commit()
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/292011.html
標籤:其他
