整合營銷服務商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          一種基于pyppeteer的新浪微博登錄方式

          一種基于pyppeteer的新浪微博登錄方式


          微博搜索采集時,默認情況下只顯示當前頁數(shù)據(jù)。如果搜索的關鍵詞是熱詞,當前頁數(shù)據(jù)的時間范圍可能只有三五分鐘。所以,如果要把數(shù)據(jù)采集全,則必須登錄。

          在大批量采集時,必須使用賬號構建cookie池,并根據(jù)cookie有效期實時更新已過期的cookie,下面主要實現(xiàn)基于Pyppeteer的微博登錄,供大家參考。

          新浪微博登錄DEMO主類:

          import asyncio, time
          from com.fy.plugs.browser.pyppeteer.PyppeteerBrowser import PyppeteerBrowser
          from com.fy.utils.date.DateUtils import Date_Utils
          class WeiBoLogin:
              def __init__(self):
                  self.pb=PyppeteerBrowser()
                  self.du=Date_Utils()
          
              def login(self):
                  url="https://passport.weibo.cn/signin/login?entry=mweibo&res=wel&wm=3349&r=https%3A%2F%2Fm.weibo.cn%2F"
                  userDataDir="d://pyppeteer" + str(self.du.getCurrentTimeStr_Year())
                  asyncio.get_event_loop() .run_until_complete(self.pb.getbrowser(False, userDataDir))
                  asyncio.get_event_loop() .run_until_complete(self.pb.open(url, 60))
                  time.sleep(10)
                  asyncio.get_event_loop() .run_until_complete(self.pb.inputKw(None, "#loginName", "用戶名"))
                  time.sleep(1) 
                  asyncio.get_event_loop() .run_until_complete(self.pb.inputKw(None, "#loginPassword", "密碼"))
                  time.sleep(1)
                  eles=asyncio.get_event_loop() .run_until_complete(self.pb.getElementsByXpaths(None, '//*[@id="loginAction"]'))
                  asyncio.get_event_loop() .run_until_complete(self.pb.clickByEle(eles[0]))
                  time.sleep(100)
          
          if __name__=='__main__':
              sbl=WeiBoLogin()
              sbl.login()
          

          Pyppeteer公共類:

          import asyncio, tkinter, traceback 
          import time
          from pyppeteer import launch
          from com.fy.utils.http.UserAgentUtils import UserAgentUtils
          from com.fy.utils.hash.HashUtils import Hash_Utils
          from com.fy.utils.file.FileUtils import File_Utils 
          class PyppeteerBrowser:
              def __init__(self):
                  self.hash=Hash_Utils()
                  self.url=None
                  self.ua=UserAgentUtils()
              
              #"""使用tkinter獲取屏幕大小""")
              def screen_size(self):
                  tk=tkinter.Tk()
                  width=tk.winfo_screenwidth()
                  height=tk.winfo_screenheight()
                  tk.quit()
                  return width, height
          
              async def getbrowser(self, headless=False, userDataDir=None):
                 
                  args=[ "--start-maximized", '--no-sandbox', "--disable-infobars" , "--log-level=3"]
                  parameters={}
                  if userDataDir==None:
                      parameters={'headless': headless, #是否打開瀏覽器;False:打開瀏覽器;True:進程中運行;
                                                 'args': args,
                                                  'dumpio': True  #'dumpio': True:解決chromium瀏覽器多開頁面卡死問題。
                                                  }
                  else:
                      parameters={'headless': headless, #是否打開瀏覽器;False:打開瀏覽器;True:進程中運行;
                                                 'args': args,
                                                 "userDataDir": userDataDir,
                                                  'dumpio': True   #'dumpio': True:解決chromium瀏覽器多開頁面卡死問題。
                                                  }
                  #注意:同一個用戶目錄(userDataDir)不能被兩個chrome進程使用,如果你要多開,記得分別指定用戶目錄。否則會報編碼錯誤。
                  self.browser=await launch(parameters)
          
                  self.page=await self.browser.newPage()#在此瀏覽器上創(chuàng)建新頁面并返回其對象。
                  
                  width, height=self.screen_size()
                  # 設置網(wǎng)頁可視區(qū)域大小
                  await self.page.setViewport({
                      "width": width,
                      "height": height
                  })
          
                  # 是否啟用JS,enabled設為False,則無渲染效果
                  await self.page.setJavaScriptEnabled(enabled=True)
          
                  #設置請求頭userAgent
                  await self.page.setUserAgent(self.ua.getheaders())
                  
                  await self.preventCheckWebdriver(self.page)
                  print("構造瀏覽器對象完畢....", self.page)
                  
              #獲取當前操作的界面  
              async def getPage(self): 
                  return  self.page
          
              #獲取當前page對象的鏈接;
              async def getCurUrl(self, page):
                  if page==None:
                      page=self.page 
                  return  await page.url
          
              #打開一個新的界面;)
              async def getnewpage(self): 
                  return  await self.browser.newPage()
          
              #獲取當前操作的界面重新加載    
              async def reload(self): 
                  await self.page.reload()   
          
              #當前操作界面返回    
              async def goBack(self): 
                  await self.page.goBack() 
          
              #獲取當前操作的界面的URL   
              async def getPageUrl(self): 
                  await self.page.url() 
          
              #打開連接;
              async def open(self, url, timeout=60):
                  try:
                      if url==None:
                          print("當前傳入的【url】不能為空,參數(shù)錯誤!!")
                      self.url=url
                      print("打開網(wǎng)頁:" + (url))      
                      self.res=await self.page.goto(url, options={'timeout':int(timeout * 1000)})#打開連接;
                      await asyncio.sleep(1)#強行等待3秒
                      status=await self.res.status
                      curUrl=await self.page.url
                      await self.preventCheckWebdriver(self.page)
                      return  status, curUrl
                  except:return  404, None
          
          async def preventCheckWebdriver(self, page):
                  if page==None:
                      page=self.page
                  await page.evaluate('''()=>{ Object.defineProperties(navigator,{ webdriver:{ get: ()=> undefined } }) }''')  # 以下為插入中間js,將淘寶會為了檢測瀏覽器而調用的js修改其結果。
                  await page.evaluate('''()=>{ window.navigator.chrome={ runtime: {},  }; }''')
                  await page.evaluate('''()=>{ Object.defineProperty(navigator, 'languages', { get: ()=> ['en-US', 'en'] }); }''')
                  await page.evaluate('''()=>{ Object.defineProperty(navigator, 'plugins', { get: ()=> [1, 2, 3, 4, 5,6], }); }''')
          
              async def closeBrowser(self, browser):
                  if browser==None:
                      browser=self.browser
                  try:
                      await browser.close()
                  except:pass
          
              async def closePage(self, page):
                  if page==None:
                      page=self.page
                  await page.close()
                  
              async def closeNumPage(self, number:"號碼從0開始"):
                  pages=await self.browser.pages()
                  await pages[number].close()
                  return True
                  
              async def retainLastPage(self):
                  pages=await self.browser.pages()
                  num=0
                  for  page in pages:
                      if num !=(len(pages) - 1):
                          await page.close()
                      else:
                          self.page=page
                      num +=1
                  
              async def gerReponseStatus(self):
                  try:return await self.res.status  # 響應狀態(tài)
                  except:return 200
          
              async def screenshot(self, page):
                  hashCode=self.hash.getMd5Hash(self.url)
                  if page==None:
                      page=self.page
                  await page.screenshot({'path': './screenshots/' + str(hashCode) + '.png'})
          
              async def getHeader(self):
                  return await self.res.headers  # 響應頭;
          
              async def scrollToButtom(self, page):
                  if page==None:
                      page=self.page
                  await page.evaluate('window.scrollBy(0, document.body.scrollHeight)')
          
              async def getCookies(self, page):
                  if page==None:
                      page=self.page
                  return await page.cookies()
          
              async def getCookieStr(page):
                  if page==None:
                      page=self.page
                  cookies_list=await page.cookies()
                  cookies=''
                  for cookie in cookies_list:
                      str_cookie='{0}={1};'
                      str_cookie=str_cookie.format(cookie.get('name'), cookie.get('value'))
                      cookies +=str_cookie
                  try:print(cookies)
                  except:pass
                  return cookies
              
              async def setCookies(self, page, cookies):
                  if page==None:
                      page=self.page
                  return await page.setCookie(*cookies)
              
              async def getHtml(self, page):
                  if page==None:
                      page=self.page
                  return (await page.content())
          
              async def getCurPageTitle(self, page):
                  if page==None:
                      page=self.page
                  return (await page.title())
          
              async def getElementFieldValue(self, page, element, field):
                  if element==None:
                      print("當前傳入的【element】不能為空,參數(shù)錯誤!!")
                      return None
                  if field==None:
                      print("當前傳入的【field】不能為空,參數(shù)錯誤!!")
                      return None
                  if page==None:
                      page=self.page
                  if str(type(element))=="<class 'list'>":
                      print("當前傳入的【element】不是單個對象,為list集合,參數(shù)錯誤!!")
                      return None
                  fieldValue=(await element.getProperty(field)).jsonValue()
                  return  fieldValue
          
              async def getPageWidthHight(self, page):
                  if page==None:
                      page=self.page
                  return  await page.evaluate('''()=> {
                              return {
                                  width: document.documentElement.clientWidth,
                                  height: document.documentElement.clientHeight,
                                  deviceScaleFactor: window.devicePixelRatio,
                              }
                          }''')
          
              async def getCurBrowserAllPages(self):
                  return await self.browser.pages()
          
              async def getElementsByXpaths(self, page, xpath:'如://div[@class="title-box"]/a'):
                  if xpath==None:
                      print("當前傳入的【xpath】不能為空,參數(shù)錯誤!!")
                      return None
                  if page==None:
                      page=self.page
                  try:elemList=await page.xpath(xpath)
                  except:
                      print("獲取xpath路徑為【" + str(xpath) + "】的標簽對象異常...")
                  return elemList#返回類型為:list集合;
          
              async def getPageText(self, page):
                  if page==None:
                      page=self.page
                  '''Pyppeteer的evaluate()方法只使用JavaScript字符串,該字符串可以是函數(shù)也可以是表達式,
                     Pyppeteer會進行自動判斷。但有時會判斷錯誤,如果字符串被判斷成了函數(shù),并且報錯,
                       可以添加選項force_expr=True,強制Pyppeteer作為表達式處理。'''
                  return await page.evaluate('document.body.textContent', force_expr=True)
                  
              async def getElementText(self, page, element):
                  if element==None:
                      print("當前傳入的【element】不能為空,參數(shù)錯誤!!")
                      return None
                  if page==None:
                      page=self.page
                  if str(type(element))=="<class 'list'>":
                      print("當前傳入的【element】不是單個對象,為list集合,參數(shù)錯誤!!")
                      return None
                  return  await page.evaluate('(element)=> element.textContent', element)
              
              async def getElementBySelector(self, page , selector):
                  if selector==None:
                      print("當前傳入的【selector】不能為空,參數(shù)錯誤!!")
                      return None
                  if page==None:
                      page=self.page
                  return  await page.querySelector(selector)
              
              async def inputKw(self, page, selector:"如:'input#kw.s_ipt':獲取input標簽中id='kw',class='s_ipt'的對象。不可用xpath路徑", kw:'待輸入的關鍵詞'):
                  if kw==None:
                      return None
                  if selector==None:
                      return None
                  if page==None:
                      page=self.page
                  try:print(selector, kw)
                  except:pass
                  await page.type(selector, kw)
                  return None
          
              async def clickElement(self, page, selector:"如:'input#kw.s_ipt':獲取input標簽中id='kw',class='s_ipt'的對象。。不可用xpath路徑"):
                  if selector==None:
                      print("當前傳入的【selector】不能為空,參數(shù)錯誤!!")
                  if page==None:
                      page=self.page
                  await page.click(selector)#如果selector獲取的對象是list集合,則執(zhí)行第一個元素的點擊;
          
              async def removeInputValue(self, page, idValue):
                  if idValue==None:
                      print("當前傳入的【idValue】不能為空,參數(shù)錯誤!!")
                  if page==None:
                      page=self.page
                  await page.evaluate("document.querySelector('#" + str(idValue) + "').value=''")
                  print("清空【" + str(idValue) + "】的內容")
          
              async def clickByEle(self, ele):
                  if ele==None:
                      return
                  return await ele.click()
                      
              async def getLastPage(self):
                  pages=await self.browser.pages()
                  return pages[-1]
                      
              async def getPageTotal(self):
                  pages=await self.browser.pages()
                  return len(pages)
                      
              async def getFirstPage(self):
                  pages=await self.browser.pages()
                  return pages[0]
                      
              async def getAllFrames(self, page):
                  if page==None:
                      page=self.page
                  return  await page.frames
          
              async def getScreenshotByEle(self, page, ele, screenshotFilePath:"目前測試只有.png圖片可正常生成,jpg異常;"):
                  picture=''
                  try:
                      fu=File_Utils(None)
                      fu=File_Utils(fu.getParentDir(screenshotFilePath))
                      if not fu.exists(fu.getParentDir(screenshotFilePath)):fu.makeDirs()#如果圖片的保存目錄不存在,則創(chuàng)建;
                      time.sleep(3)
                      try:
                          for _ in range(6):
                              clip=await ele.boundingBox()
                              picture=base64.b64encode(await page.screenshot({
                                  'path': screenshotFilePath, # 圖片路徑, 不指定就不保存
                                  'clip': clip # 指定圖片位置,大小
                              }))
                              if picture !='':
                                  break
                      except Exception as e:
                          print(traceback.print_exc())
                  except Exception as e:
                      print(traceback.print_exc())
                  return picture

          注意事項:

          測試過程中發(fā)現(xiàn),基于PC端的登錄界面,在Pyppeteer瀏覽器中,登錄按鈕無法使用。但是手機端登錄界面可以正常登錄

          午已經(jīng)說完了CSS文本樣式,接著說下CSS的引入方式,包含內部樣式表(嵌入式),行內樣式表(行內式)和外部樣式表(鏈接式)。

          內部樣式表(內嵌樣式表)是寫道HTML頁面內部,是將所有的CSS代碼抽取出來,單獨放到一個<style>?標簽中。

          以前的語法展示:

          <style>

          ? ?div {

          ? ?color:pink;

          font-size:12px;

          ?}

          </style>

          將所有的樣式,都放到<style>標簽中

          展示如下:

          對應的代碼如下:

          <!DOCTYPE html>

          <html lang="en">

          <head>

          <meta charset="UTF-8">

          <meta http-equiv="X-UA-Compatible" content="IE=edge">

          <meta name="viewport" content="width=device-width, initial-scale=1.0">

          <title>CSS引入方式-內部樣式表</title>

          <!-- 將所有的樣式都放在一個<style>標簽中 -->

          <style>

          div {

          /* 文本顏色屬性 */

          color: blue;

          /* 文本行間距 */

          line-height: 32px;

          /* 讓文本在中間展示 */

          text-align: center;

          }


          p {

          /* 段落首行收縮2個字 */

          text-indent: 2em;

          }


          a {

          /* 文本不展示下劃線 */

          text-decoration: none;

          }


          </style>

          </head>

          <body>

          <div>戰(zhàn)無不勝,攻無不克,橫刀立馬,千秋萬代</div>


          <p>10月15日晚,甘肅省天水市婦女聯(lián)合會官方微博發(fā)布通報稱,經(jīng)過多方勸解,孩子父親毛某已于10月14日將孩子送到母親范某身邊。目前孩子健康狀況良好,范某情緒穩(wěn)定,毛某也認識到因自己一時沖動造成的嚴重后果,并保證不再有過激行為。</p>


          <div>一片祥云,我自橫刀向天笑</div>


          <!-- 下劃線展示 -->

          文本不展示下劃線<br/>

          <a href="www.baidu.com">跳轉到百度頁面</a>

          </body>

          </html>


          <style>標簽理論上可以放到HTML文檔的任何地方,但一般會放在文檔的<head>?標簽中。通過此種方式,可以方便控制當前整個頁面中的?元素樣式設置。代碼結構非常清晰,但是并沒有實現(xiàn)?結構與樣式完全分離。使用內部樣式設定CSS,通常也被成為嵌入式引入,?這種方式是我們練習時的常用方式。

          我向您講授了如何向 html 頁面添加 JavaScript,使得網(wǎng)站的動態(tài)性和交互性更強。

          你已經(jīng)學習了如何創(chuàng)建對事件的響應,驗證表單,以及如何根據(jù)不同的情況運行不同的腳本。

          你也學到了如何創(chuàng)建和使用對象,以及如何使用 JavaScript 的內置對象。

          如需更多關于 JavaScript 的信息和知識,請參閱我的 JavaScript 實例 和 JavaScript 參考手冊。

          現(xiàn)在已經(jīng)你已經(jīng)學習了 JavaScript,接下來該學習什么呢?

          下一步應該學習 HTML DOM 和 DHTML。

          如果你希望學習關于服務器端腳本的知識,那么下一步應該學習 ASP,PHP, .Net。

          HTML DOM

          HTML DOM 定義了訪問和操作 HTML 文檔的標準方法。 HTML DOM 獨立于平臺和語言,可被任何編程語言使用,比如 Java、JavaScript 和 VBscript。

          jQuery

          jQuery 是一個 JavaScript 庫。

          jQuery 極大地簡化了 JavaScript 編程。

          jQuery 很容易學習。

          AJAX

          AJAX=異步 JavaScript 和 XML。

          AJAX 不是一種新的編程語言,而是一種使用現(xiàn)有標準的新方法。

          通過與服務器進行數(shù)據(jù)交換,AJAX 可以在不重新加載整個網(wǎng)頁的情況下,對網(wǎng)頁的某部分進行更新。

          有很多使用 AJAX 的應用程序案例:新浪微博、Google 地圖、開心網(wǎng)等等。

          ASP / PHP / .NET

          和 HTML 文檔中的腳本運行于客戶端(瀏覽器)不同,ASP/PHP 文件中的腳本在服務器上運行。

          使用 ASP,你可以動態(tài)地編輯、改變或者添加網(wǎng)站內容,對由 HTML 表單提交而來的數(shù)據(jù)進行響應,訪問數(shù)據(jù)或者數(shù)據(jù)庫并向瀏覽器返回結果,或者定制對不同的用戶來說更有幫助的網(wǎng)頁。

          由于 ASP/PHP 文件返回的是純粹的 HTML,因此可顯示在任何瀏覽器中。

          如您還有不明白的可以在下面與我留言或是與我探討QQ群308855039,我們一起飛!


          主站蜘蛛池模板: 精品国产日韩一区三区| 国产一区三区三区| 一区在线观看视频| 高清国产AV一区二区三区| 亚洲一区二区三区在线 | 国产经典一区二区三区蜜芽 | 无码一区二区三区在线观看| 国产激情无码一区二区app| 午夜福利一区二区三区在线观看 | 精品一区二区三区四区| 亚洲视频一区网站| 日韩一区二区在线免费观看| 国产一区二区三区夜色 | 无码人妻精品一区二区三区99仓本 | 亚洲AV无码一区二区乱孑伦AS| 中文字幕一区二区三区在线不卡| 久久久久久免费一区二区三区| 性色AV一区二区三区天美传媒| 亚洲日本一区二区三区在线不卡| 国产一区二区免费视频| 少妇一夜三次一区二区| 真实国产乱子伦精品一区二区三区| 少妇精品久久久一区二区三区| 国产福利无码一区在线| 奇米精品一区二区三区在| 亚洲日韩AV一区二区三区中文 | 精品人妻中文av一区二区三区 | 国产AV午夜精品一区二区入口 | 日韩免费无码视频一区二区三区 | 国产视频一区二区| 亚洲日本精品一区二区| 国产一区二区三区在线观看影院 | 国产日韩高清一区二区三区| 91视频国产一区| 国产综合精品一区二区三区| 黑人一区二区三区中文字幕| 男插女高潮一区二区| 国产剧情国产精品一区| 日韩精品一区二区三区影院| 亚洲精品日韩一区二区小说| 久久久精品人妻一区亚美研究所|