通過(guò)Python爬取當(dāng)當(dāng)網(wǎng),學(xué)正則表達(dá)式

前言

在上一篇文章中講述了正則表達(dá)式的使用方法,既然講了那不來(lái)點(diǎn)實(shí)戰(zhàn)性的文章嘛?那肯定是不行的,所以這次我就是用正則表達(dá)式爬取當(dāng)當(dāng)網(wǎng)的TOP500的圖書(shū)。

準(zhǔn)備工作

工欲善其事,必先利其器。寫代碼也同樣是如此,所以在開(kāi)始之前請(qǐng)先安裝好requestst、pandas庫(kù)。如果沒(méi)有安裝,請(qǐng)先安裝好。

# 安裝requests
pip install requests

# 安裝pandas
pip install pandas

需求分析

本次我們需要提取出當(dāng)當(dāng)網(wǎng)TOP500的圖書(shū)名稱、初版時(shí)間、價(jià)格和作者姓名。

獲取書(shū)籍名稱

首先打開(kāi)開(kāi)發(fā)者工具,使用選擇器定位到書(shū)籍名稱。

image

從上圖可以看到,書(shū)籍名稱在title屬性值上。

具體正則表達(dá)式如下所示:

pattern_name = re.compile('li.*?<div class="name">.*?title="(.*?)".*?</a>', re.S)

獲取作者姓名

image

從上圖可以看到作者姓名在a標(biāo)簽的文本中,具體正則表達(dá)式代碼如下所示:

 pattern_author = re.compile('li.*?<div class="publisher_info">.*?<a .*?target="_blank">(.*?)</a>', re.S)

獲取出版日期

image

從上圖可以看到,出版日期在span標(biāo)簽內(nèi)。具體正則表達(dá)式如下所示:

 pattern_time = re.compile('li.*?<div class="publisher_info">.*?<span>(.*?)</span>', re.S)

獲取價(jià)格

image

和出本日期一樣,都是在span標(biāo)簽內(nèi),但是要注意它們之間的區(qū)別。具體正則表達(dá)式如下所示:

pattern_price = re.compile('li.*?<div class="price">.*?<span class="price_n">(.*?)</span>', re.S)

翻頁(yè)處理

打開(kāi)網(wǎng)頁(yè)你會(huì)發(fā)現(xiàn)并不是所有的的圖書(shū)都在同一個(gè)頁(yè)面,TOP500共有25頁(yè),每頁(yè)20本書(shū)。所以接下來(lái)需要分析翻頁(yè)時(shí)URL的變化規(guī)律。

# 第一頁(yè)
http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1
# 第二頁(yè)
http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-2
# 第二十五頁(yè)
http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-25

從上面不難看出變化的內(nèi)容是最后一個(gè)數(shù)字,并且每一次都按加1的操作。

功能實(shí)現(xiàn)

獲取每一頁(yè)的URL地址

    def get_url(self, page):
        url = f'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-{page}'
        return url

可以通過(guò)循環(huán)的方式,將1-25傳值給page

獲取每一頁(yè)的網(wǎng)頁(yè)信息

    def get_html(self, url):
        html = self.session.get(url).content.decode('gb2312', 'ignore')
        return html

將信息保存至csv文件

    def get_info(self, html):
        pattern_name = re.compile('li.*?<div class="name">.*?title="(.*?)".*?</a>', re.S)
        pattern_author = re.compile('li.*?<div class="publisher_info">.*?<a .*?target="_blank">(.*?)</a>', re.S)
        pattern_time = re.compile('li.*?<div class="publisher_info">.*?<span>(.*?)</span>', re.S)
        pattern_price = re.compile('li.*?<div class="price">.*?<span class="price_n">(.*?)</span>', re.S)
        name = re.findall(pattern_name, html)
        author = re.findall(pattern_author, html)
        print('清洗前:',author)
        # author = [i for i in author if '出版社' not in i]
        if page == 3:
            author = [i for i in author if '出版社' not in i]
        if page == 14:
            author = [i for i in author if '機(jī)械工業(yè)出版社' not in i]
        print('清洗后:',author)
        print(len(author))
        time = re.findall(pattern_time, html)
        price = re.findall(pattern_price, html)
        price = [i.replace('&yen;', '¥') for i in price]
        df = pd.DataFrame({
            'book_name': name,
            'author': author,
            'edition_time': time,
            'price': price
        })
        print(list(df['author']))
        return df

在這里我需要說(shuō)兩個(gè)坑,也就是上面代碼的兩個(gè)if語(yǔ)句

這兩個(gè)坑是這樣的,當(dāng)匹配到第三頁(yè)和第第十四頁(yè)的時(shí)候,分別有一本書(shū)會(huì)出現(xiàn)兩個(gè)作者信息,一個(gè)是作者,一個(gè)是出版社信息。那這樣就會(huì)出現(xiàn)21個(gè)作者,20本書(shū)21個(gè)作者顯然是不合理的,所以我使用兩個(gè)if語(yǔ)句將這兩個(gè)多余內(nèi)容清理掉。

最后

本次爬取當(dāng)當(dāng)網(wǎng)的內(nèi)容分享到這里就結(jié)束了,你將正則表達(dá)式學(xué)會(huì)了嗎?

如果你看到這里,相信本文對(duì)你還是有些許幫助的,這也是我寫文章的初衷。

路漫漫其修遠(yuǎn)兮,吾將上下而求索。

我是啃書(shū)君,一個(gè)專注于學(xué)習(xí)的人,你懂的越多,你不懂的越多。更多精彩內(nèi)容,我們下期再見(jiàn)!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容