1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        數(shù)據(jù)采集和解析

        共 8256字,需瀏覽 17分鐘

         ·

        2021-10-10 08:48

        1. 下載數(shù)據(jù) - 「urllib」 / 「requests」 / 「aiohttp」 / 「httpx」。
        2. 解析數(shù)據(jù) - 「re」 / 「lxml」 / 「beautifulsoup4」 / 「pyquery」。
        3. 緩存和持久化 - 「mysqlclient」 / 「sqlalchemy」 / 「peewee」 / 「redis」 / 「pymongo」。
        4. 生成數(shù)字簽名 - 「hashlib」。
        5. 序列化和壓縮 - 「pickle」 / 「json」 / 「zlib」。
        6. 調(diào)度器 - 「multiprocessing」 / 「threading」 / 「concurrent.futures」

        HTML頁面

        html>
        <html>
        ?<head>
        ??<title>Hometitle>
        ??<style?type="text/css">
        ???/*?此處省略層疊樣式表代碼?*/
        ??
        style>
        ?head>
        ?<body>
        ??<div?class="wrapper">
        ???<header>
        ????<h1>Yoko's?Kitchenh1>
        ????<nav>
        ?????<ul>
        ??????<li><a?href=""?class="current">Homea>li>
        ??????<li><a?href="">Classesa>li>
        ??????<li><a?href="">Cateringa>li>
        ??????<li><a?href="">Abouta>li>
        ??????<li><a?href="">Contacta>li>
        ?????ul>
        ????nav>
        ???header>
        ???<section?class="courses">
        ????<article>
        ?????<figure>
        ??????<img?src="images/bok-choi.jpg"?alt="Bok?Choi"?/>
        ??????<figcaption>Bok?Choifigcaption>
        ?????figure>
        ?????<hgroup>
        ??????<h2>Japanese?Vegetarianh2>
        ??????<h3>Five?week?course?in?Londonh3>
        ?????hgroup>
        ?????<p>A?five?week?introduction?to?traditional?Japanese?vegetarian?meals,?teaching?you?a?selection?of?rice?and?noodle?dishes.p>
        ????article>????
        ????<article>
        ?????<figure>
        ??????<img?src="images/teriyaki.jpg"?alt="Teriyaki?sauce"?/>
        ??????<figcaption>Teriyaki?Saucefigcaption>
        ?????figure>
        ?????<hgroup>
        ??????<h2>Sauces?Masterclassh2>
        ??????<h3>One?day?workshoph3>
        ?????hgroup>
        ?????<p>An?intensive?one-day?course?looking?at?how?to?create?the?most?delicious?sauces?for?use?in?a?range?of?Japanese?cookery.p>
        ????article>????
        ???section>
        ???<aside>
        ????<section?class="popular-recipes">
        ?????<h2>Popular?Recipesh2>
        ?????<a?href="">Yakitori?(grilled?chicken)a>
        ?????<a?href="">Tsukune?(minced?chicken?patties)a>
        ?????<a?href="">Okonomiyaki?(savory?pancakes)a>
        ?????<a?href="">Mizutaki?(chicken?stew)a>
        ????section>
        ????<section?class="contact-details">
        ?????<h2>Contacth2>
        ?????<p>Yoko's?Kitchen<br>
        ??????27?Redchurch?Street<br>
        ??????Shoreditch<br>
        ??????London?E2?7DPp>
        ????section>
        ???aside>
        ???<footer>
        ????©?2011?Yoko's?Kitchen
        ???footer>
        ??div>
        ????????<script>
        ?????????/*?此處省略JavaScript代碼?*/
        ????????
        script>
        ?body>
        html>

        如上所示的HTML頁面通常由三部分構(gòu)成,分別是用來承載內(nèi)容的Tag(標(biāo)簽)、負(fù)責(zé)渲染頁面的CSS(層疊樣式表)以及控制交互式行為的JavaScript。通常,我們可以在瀏覽器的右鍵菜單中通過“查看網(wǎng)頁源代碼”的方式獲取網(wǎng)頁的代碼并了解頁面的結(jié)構(gòu);當(dāng)然,我們也可以通過瀏覽器提供的開發(fā)人員工具來了解更多的信息。

        使用requests獲取頁面

        在上一節(jié)課的代碼中我們使用了三方庫requests來獲取頁面,下面我們對requests庫的用法做進(jìn)一步說明。

        1. GET請求和POST請求。

          import?requests

          resp?=?requests.get('http://www.baidu.com/index.html')
          print(resp.status_code)
          print(resp.headers)
          print(resp.cookies)
          print(resp.content.decode('utf-8'))

          resp?=?requests.post('http://httpbin.org/post',?data={'name':?'Hao',?'age':?40})
          print(resp.text)
          data?=?resp.json()
          print(type(data))
        2. URL參數(shù)和請求頭。

          resp?=?requests.get(
          ????url='https://movie.douban.com/top250',
          ????headers={
          ????????'User-Agent':?'Mozilla/5.0?(Macintosh;?Intel?Mac?OS?X?10_14_6)?'
          ??????????????????????'AppleWebKit/537.36?(KHTML,?like?Gecko)?'
          ??????????????????????'Chrome/83.0.4103.97?Safari/537.36',
          ????????'Accept':?'text/html,application/xhtml+xml,application/xml;'
          ??????????????????'q=0.9,image/webp,image/apng,*/*;'
          ??????????????????'q=0.8,application/signed-exchange;v=b3;q=0.9',
          ????????'Accept-Language':?'zh-CN,zh;q=0.9,en;q=0.8',
          ????}
          )
          print(resp.status_code)
        3. 復(fù)雜的POST請求(文件上傳)。

          resp?=?requests.post(
          ?url='http://httpbin.org/post',
          ????files={'file':?open('data.xlsx',?'rb')}
          )
          print(resp.text)
        4. 操作Cookie。

          cookies?=?{'key1':?'value1',?'key2':?'value2'}
          resp?=?requests.get('http://httpbin.org/cookies',?cookies=cookies)
          print(resp.text)

          jar?=?requests.cookies.RequestsCookieJar()
          jar.set('tasty_cookie',?'yum',?domain='httpbin.org',?path='/cookies')
          jar.set('gross_cookie',?'blech',?domain='httpbin.org',?path='/elsewhere')
          resp?=?requests.get('http://httpbin.org/cookies',?cookies=jar)
          print(resp.text)
        5. 設(shè)置代理服務(wù)器。

          requests.get('https://www.taobao.com',?proxies={
          ????'http':?'http://10.10.1.10:3128',
          ????'https':?'http://10.10.1.10:1080',
          })

          「說明」:關(guān)于requests庫的相關(guān)知識,還是強烈建議大家自行閱讀它的官方文檔。

        6. 設(shè)置請求超時。

          requests.get('https://github.com',?timeout=10)

        頁面解析

        幾種解析方式的比較

        解析方式對應(yīng)的模塊速度使用難度備注
        正則表達(dá)式解析re困難常用正則表達(dá)式
        在線正則表達(dá)式測試
        XPath解析lxml一般需要安裝C語言依賴庫
        唯一支持XML的解析器
        CSS選擇器解析bs4 / pyquery不確定簡單

        「說明」BeautifulSoup可選的解析器包括:Python標(biāo)準(zhǔn)庫中的html.parser、lxml的HTML解析器、lxml的XML解析器和html5lib

        使用正則表達(dá)式解析頁面

        如果你對正則表達(dá)式?jīng)]有任何的概念,那么推薦先閱讀《正則表達(dá)式30分鐘入門教程》,然后再閱讀我們之前講解在Python中如何使用正則表達(dá)式一文。

        下面的例子演示了如何用正則表達(dá)式解析“豆瓣電影Top250”中的中文電影名稱。

        import?random
        import?re
        import?time

        import?requests

        PATTERN?=?re.compile(r']*?>\s*(.*?)')

        for?page?in?range(10):
        ????resp?=?requests.get(
        ????????url=f'https://movie.douban.com/top250?start={page?*?25}',
        ????????headers={
        ????????????'User-Agent':?'Mozilla/5.0?(Macintosh;?Intel?Mac?OS?X?10_14_6)?'
        ??????????????????????????'AppleWebKit/537.36?(KHTML,?like?Gecko)?'
        ??????????????????????????'Chrome/83.0.4103.97?Safari/537.36',
        ????????????'Accept':?'text/html,application/xhtml+xml,application/xml;'
        ??????????????????????'q=0.9,image/webp,image/apng,*/*;'
        ??????????????????????'q=0.8,application/signed-exchange;v=b3;q=0.9',
        ????????????'Accept-Language':?'zh-CN,zh;q=0.9,en;q=0.8',
        ????????},
        ????)
        ????items?=?PATTERN.findall(resp.text)
        ????for?item?in?items:
        ????????print(item)
        ????time.sleep(random.randint(1,?5))

        XPath解析和lxml

        XPath是在XML文檔中查找信息的一種語法,它使用路徑表達(dá)式來選取XML文檔中的節(jié)點或者節(jié)點集。這里所說的XPath節(jié)點包括元素、屬性、文本、命名空間、處理指令、注釋、根節(jié)點等。


        <bookstore>
        ????<book>
        ??????<title?lang="eng">Harry?Pottertitle>
        ??????<price>29.99price>
        ????book>
        ????<book>
        ??????<title?lang="zh">三國演義title>
        ??????<price>39.95price>
        ????book>
        bookstore>

        對于上面的XML文件,我們可以用如下所示的XPath語法獲取文檔中的節(jié)點。

        路徑表達(dá)式結(jié)果
        bookstore選取 bookstore 元素的所有子節(jié)點。
        /bookstore選取根元素 bookstore。注釋:假如路徑起始于正斜杠( / ),則此路徑始終代表到某元素的絕對路徑!
        bookstore/book選取屬于 bookstore 的子元素的所有 book 元素。
        //book選取所有 book 子元素,而不管它們在文檔中的位置。
        bookstore//book選擇屬于 bookstore 元素的后代的所有 book 元素,而不管它們位于 bookstore 之下的什么位置。
        //@lang選取名為 lang 的所有屬性。

        在使用XPath語法時,還可以使用XPath中的謂詞。

        路徑表達(dá)式結(jié)果
        /bookstore/book[1]選取屬于 bookstore 子元素的第一個 book 元素。
        /bookstore/book[last()]選取屬于 bookstore 子元素的最后一個 book 元素。
        /bookstore/book[last()-1]選取屬于 bookstore 子元素的倒數(shù)第二個 book 元素。
        /bookstore/book[position()<3]選取最前面的兩個屬于 bookstore 元素的子元素的 book 元素。
        //title[@lang]選取所有擁有名為 lang 的屬性的 title 元素。
        //title[@lang='eng']選取所有 title 元素,且這些元素?fù)碛兄禐?eng 的 lang 屬性。
        /bookstore/book[price>35.00]選取 bookstore 元素的所有 book 元素,且其中的 price 元素的值須大于 35.00。
        /bookstore/book[price>35.00]/title選取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值須大于 35.00。

        XPath還支持通配符用法,如下所示。

        路徑表達(dá)式結(jié)果
        /bookstore/*選取 bookstore 元素的所有子元素。
        //*選取文檔中的所有元素。
        //title[@*]選取所有帶有屬性的 title 元素。

        如果要選取多個節(jié)點,可以使用如下所示的方法。

        路徑表達(dá)式結(jié)果
        //book/title | //book/price選取 book 元素的所有 title 和 price 元素。
        //title | //price選取文檔中的所有 title 和 price 元素。
        /bookstore/book/title | //price選取屬于 bookstore 元素的 book 元素的所有 title 元素,以及文檔中所有的 price 元素。

        「說明」:上面的例子來自于菜鳥教程網(wǎng)站上XPath教程,有興趣的讀者可以自行閱讀原文。

        當(dāng)然,如果不理解或者不太熟悉XPath語法,可以在Chrome瀏覽器中按照如下所示的方法查看元素的XPath語法。

        下面的例子演示了如何用XPath解析“豆瓣電影Top250”中的中文電影名稱。

        from?lxml?import?etree

        import?requests

        for?page?in?range(10):
        ????resp?=?requests.get(
        ????????url=f'https://movie.douban.com/top250?start={page?*?25}',
        ????????headers={
        ????????????'User-Agent':?'Mozilla/5.0?(Macintosh;?Intel?Mac?OS?X?10_14_6)?'
        ??????????????????????????'AppleWebKit/537.36?(KHTML,?like?Gecko)?'
        ??????????????????????????'Chrome/83.0.4103.97?Safari/537.36',
        ????????????'Accept':?'text/html,application/xhtml+xml,application/xml;'
        ??????????????????????'q=0.9,image/webp,image/apng,*/*;'
        ??????????????????????'q=0.8,application/signed-exchange;v=b3;q=0.9',
        ????????????'Accept-Language':?'zh-CN,zh;q=0.9,en;q=0.8',
        ????????}
        ????)
        ????html?=?etree.HTML(resp.text)
        ????spans?=?html.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li/div/div[2]/div[1]/a/span[1]')
        ????for?span in?spans:
        ????????print(span.text)

        BeautifulSoup的使用

        BeautifulSoup是一個可以從HTML或XML文件中提取數(shù)據(jù)的Python庫。它能夠通過你喜歡的轉(zhuǎn)換器實現(xiàn)慣用的文檔導(dǎo)航、查找、修改文檔的方式。

        1. 遍歷文檔樹
          • 獲取標(biāo)簽
          • 獲取標(biāo)簽屬性
          • 獲取標(biāo)簽內(nèi)容
          • 獲取子(孫)節(jié)點
          • 獲取父節(jié)點/祖先節(jié)點
          • 獲取兄弟節(jié)點
        2. 搜索樹節(jié)點
          • find / find_all
          • select_one / select

        「說明」:更多內(nèi)容可以參考BeautifulSoup的官方文檔。

        下面的例子演示了如何用CSS選擇器解析“豆瓣電影Top250”中的中文電影名稱。

        import?random
        import?time

        import?bs4
        import?requests

        for?page?in?range(10):
        ????resp?=?requests.get(
        ????????url=f'https://movie.douban.com/top250?start={page?*?25}',
        ????????headers={
        ????????????'User-Agent':?'Mozilla/5.0?(Macintosh;?Intel?Mac?OS?X?10_14_6)?'
        ??????????????????????????'AppleWebKit/537.36?(KHTML,?like?Gecko)?'
        ??????????????????????????'Chrome/83.0.4103.97?Safari/537.36',
        ????????????'Accept':?'text/html,application/xhtml+xml,application/xml;'
        ??????????????????????'q=0.9,image/webp,image/apng,*/*;'
        ??????????????????????'q=0.8,application/signed-exchange;v=b3;q=0.9',
        ????????????'Accept-Language':?'zh-CN,zh;q=0.9,en;q=0.8',
        ????????},
        ????)
        ????soup?=?bs4.BeautifulSoup(resp.text,?'lxml')
        ????elements?=?soup.select('.info>div>a')
        ????for?element?in?elements:
        ????????span =?element.select_one('.title')
        ????????print(span.text)
        ????time.sleep(random.random()?*?5)

        例子 - 獲取知乎發(fā)現(xiàn)上的問題鏈接

        import?re
        from?urllib.parse?import?urljoin

        import?bs4
        import?requests


        def?main():
        ????headers?=?{'user-agent':?'Baiduspider'}
        ????base_url?=?'https://www.zhihu.com/'
        ????resp?=?requests.get(urljoin(base_url,?'explore'),?headers=headers)
        ????soup?=?bs4.BeautifulSoup(resp.text,?'lxml')
        ????href_regex?=?re.compile(r'^/question')
        ????links_set?=?set()
        ????for?a_tag?in?soup.find_all('a',?{'href':?href_regex}):
        ????????if?'href'?in?a_tag.attrs:
        ????????????href?=?a_tag.attrs['href']
        ????????????full_url?=?urljoin(base_url,?href)
        ????????????links_set.add(full_url)
        ????print('Total?%d?question?pages?found.'?%?len(links_set))
        ????print(links_set)


        if?__name__?==?'__main__':
        ????main()


        瀏覽 24
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            无码av看片一区二区 | 少妇做受高潮 | 国产一级一区 | 四虎成人精品永久免费AV九九 | 亚洲九九在线 | jizz性欧美19 | 国产成人无码视频 | 91丨露脸丨熟女抽搐 | 三级特黄特色视频 | 美女免费黄 |