關閉

                  一文談談我對Python爬蟲的理解(2)

                  發表于:2021-10-19 09:47

                  字體: | 上一篇 | 下一篇 | 我要投稿

                   作者:howie6879    來源:思否

                  #
                  Python
                    怎么寫爬蟲
                    網頁世界多姿多彩、億萬網頁資源供你選擇,面對不同的頁面,怎么使自己編寫的爬蟲程序夠穩健、持久,這是一個值得討論的問題。
                    俗話說,磨刀不誤砍柴工,在開始編寫爬蟲之前,很有必要掌握一些基本知識:
                    ·網頁的結構是HTML,爬蟲的目標就是解析HTML,獲取目標字段并保存
                    ·客戶端展現的網頁由瀏覽器渲染,客戶端和服務端的信息交互依靠HTTP協議
                    這兩句描述體現了一名爬蟲開發人員需要掌握的基本知識,不過一名基本的后端或者前端工程師都會這些哈哈,這也說明了爬蟲的入門難度極低,從這兩句話,你能思考出哪些爬蟲必備的知識點呢?
                    ·基本的HTML知識,了解HTML才方便目標信息提取
                    ·基本的JS知識 ,JS可以異步加載HTML
                    ·了解CSS Selector、XPath以及正則,目的是為了提取數據
                    ·了解HTTP協議,為后面的反爬蟲斗爭打下基礎
                    ·了解基本的數據庫操作,為了數據持久化
                    有了這些知識儲備,接下來就可以選擇一門語言,開始編寫自己的爬蟲程序了,還是按照上一節說的三個步驟,然后以Python為例,說一說要在編程語言方面做那些準備:
                    ·網頁請求:內置有urllib庫,第三方庫的話,同步請求可以使用requests,異步請求使用aiohttp
                    ·分析HTML結構并提取目標元素:CSS Selector和XPath是目前主流的提取方式,第三方庫可以使用Beautiful Soup或者PyQuery
                    ·數據持久化:目標數據提取之后,可以將數據保存到數據庫中進行持久化,MySQL、MongoDB等,這些都有對應的庫支持,當然你也可以保存在硬盤,誰硬盤沒點東西對吧(滑稽臉)
                    掌握了上面這些,你大可放開手腳大干一場,萬維網就是你的名利場,去吧~
                    我覺得對于一個目標網站的網頁,可以分下面四個類型:
                    ·單頁面單目標
                    ·單頁面多目標
                    ·多頁面單目標
                    ·多頁面多目標
                    具體是什么意思呢,可能看起來有點繞,但明白這些,你之后寫爬蟲,只要在腦子里面過一遍著網頁對應什么類型,然后套上對應類型的程序(寫多了都應該有一套自己的常用代碼庫),那寫爬蟲的速度,自然不會慢!

                    單頁面單目標
                    通俗來說,就是在這個網頁里面,我們的目標就只有一個,假設我們的需求是抓取這部 電影-肖申克的救贖 的名稱,首先打開網頁右鍵審查元素,找到電影名稱對應的元素位置,如下圖所示:

                    在某個單一頁面內,看目標是不是只有一個,一眼就能看出標題的CSS Selector規則為:#content > h1 > span:nth-child(1),然后用我自己寫的常用庫,我用不到十行代碼就能寫完抓取這個頁面電影名稱的爬蟲:
                  import asyncio

                  from ruia import Item, TextField

                  class DoubanItem(Item):
                      title = TextField(css_select='#content > h1 > span:nth-child(1)')

                  async_func = DoubanItem.get_item(url="https://movie.douban.com/subject/1292052/")
                  item = asyncio.get_event_loop().run_until_complete(async_func)
                  print(item.title)

                    多頁面多目標就是此情況下多個url的衍生情況。

                    單頁面多目標
                    假設現在的需求是抓取 豆瓣電影250 第一頁中的所有電影名稱,你需要提取25個電影名稱,因為這個目標頁的目標數據是多個item的,因此目標需要循環獲取,這就是所謂的單頁面多目標了:

                  import asyncio

                  from ruia import Item, TextField

                  class DoubanItem(Item):
                      target_item = TextField(css_select='div.item')
                      title = TextField(css_select='span.title')

                      async def clean_title(self, title):
                          if isinstance(title, str):
                              return title
                          else:
                              return ''.join([i.text.strip().replace('\xa0', '') for i in title])


                  async_func = DoubanItem.get_items(url="https://movie.douban.com/top250")
                  items = asyncio.get_event_loop().run_until_complete(async_func)
                  for item in items:
                      print(item)

                    多頁面多目標
                    多頁面多目標是上述單頁面多目標情況的衍生,在這個問題上來看,此時就是獲取所有分頁的電影名稱:
                  from ruia import TextField, Item, Request, Spider


                  class DoubanItem(Item):
                      """
                      定義爬蟲的目標字段
                      """
                      target_item = TextField(css_select='div.item')
                      title = TextField(css_select='span.title')

                      async def clean_title(self, title):
                          if isinstance(title, str):
                              return title
                          else:
                              return ''.join([i.text.strip().replace('\xa0', '') for i in title])


                  class DoubanSpider(Spider):
                      start_urls = ['https://movie.douban.com/top250']
                      concurrency = 10

                      async def parse(self, res):
                          etree = res.html_etree
                          pages = ['?start=0&filter='] + [i.get('href') for i in etree.cssselect('.paginator>a')]

                          for index, page in enumerate(pages):
                              url = self.start_urls[0] + page
                              yield Request(
                                  url,
                                  callback=self.parse_item,
                                  metadata={'index': index},
                                  request_config=self.request_config
                              )

                      async def parse_item(self, res):
                          items_data = await DoubanItem.get_items(html=res.html)
                          res_list = []
                          for item in items_data:
                              res_list.append(item.title)
                          return res_list


                  if __name__ == '__main__':
                      DoubanSpider.start()

                    如果網絡沒問題的話,會得到如下輸出:

                    注意爬蟲運行時間,1s不到,這就是異步的魅力。
                    用Python寫爬蟲,就是這么簡單優雅,諸位,看著網頁就思考下:
                    ·是什么類型的目標類型
                    ·用什么庫模擬請求
                    ·怎么解析目標字段
                    ·怎么存儲
                    一個爬蟲程序就成型了,順便一提,爬蟲這東西,可以說是防君子不防小人,robots.txt大部分網站都有(它的目的是告訴爬蟲什么可以爬取什么不可以爬取,比如:https://www.baidu.com/robots.txt),各位想怎么爬取,自己衡量。

                    本文內容不用于商業目的,如涉及知識產權問題,請權利人聯系51Testing小編(021-64471599-8017),我們將立即處理
                  《2023軟件測試行業現狀調查報告》獨家發布~

                  關注51Testing

                  聯系我們

                  快捷面板 站點地圖 聯系我們 廣告服務 關于我們 站長統計 發展歷程

                  法律顧問:上海蘭迪律師事務所 項棋律師
                  版權所有 上海博為峰軟件技術股份有限公司 Copyright©51testing.com 2003-2024
                  投訴及意見反饋:webmaster@51testing.com; 業務聯系:service@51testing.com 021-64471599-8017

                  滬ICP備05003035號

                  滬公網安備 31010102002173號

                  亚洲欧洲自拍图片专区123_久久久精品人妻无码专区不卡_青青精品视频国产色天使_A免看的日黄亚洲