美文网首页
用requests和正则表达式爬取豆瓣新书的信息

用requests和正则表达式爬取豆瓣新书的信息

作者: bf3780a4db09 | 来源:发表于2019-01-15 16:59 被阅读9次

最近在看崔庆才老师的爬虫视频,这里借鉴一下视频的代码做一个豆瓣新书的爬虫,主要是熟悉一下爬虫的流程,不用解析库是想熟悉一下正则表达式和网页结构,本来想爬当当网的,那个网页结构有点复杂,正则表达式没写出来。。。打算后面用解析库试试。下面说一下整个流程:
1)抓取网页,函数get_page(url);
2)解析网页内容,函数parse_page(html);
3)存入文档,函数write_to_file(content)。
下面是整个代码
粗糙版

import json
import requests
import re
for i in range(3):
    page = i+1
    url = 'https://market.douban.com/book/?utm_campaign=book_nav_freyr&utm_source=douban&utm_medium=pc_web&page='\
          + str(page) + '&page_num=18&'
    response = requests.get(url).text
    pattern = re.compile('<li.*?bookface-img">.*?src="(.*?)".*?book-price.*?<i>(.*?)</i>.*?book-brief.*?'
                         + '<h3>(.*?)</h3>.*?</li>', re.S)
    result = re.findall(pattern, response)
    for item in result:
        yiel = {
            'faceimg': item[0],
            'price': item[1],
            'brief': item[2]
        }
        print(yiel)
        with open('r1.txt', 'a', encoding='utf-8') as f:
            f.write(json.dumps(yiel, ensure_ascii=False) + '\n')
            f.close()



精致版

import json
import requests
import re
from requests.exceptions import RequestException


def get_page(url):
    try:
        response = requests.get(url)
        if response.status_code == 200:
            return response.text
        return None
    except RequestException:
        return None


def parse_page(html):
    pattern = re.compile('<li.*?bookface-img">.*?src="(.*?)".*?book-price.*?<i>(.*?)</i>.*?book-brief.*?'
                         + '<h3>(.*?)</h3>.*?</li>', re.S)
    result = re.findall(pattern, html)
    for item in result:
        yield {
            'faceimg': item[0],
            'price': item[1],
            'brief': item[2]
        }


def write_to_file(content):
    with open('result.txt', 'a', encoding='utf-8') as f:
        f.write(json.dumps(content, ensure_ascii=False) + '\n')  # 把字典转换成字符串 json.loads()把字符串转换成字典
        f.close()


def main(page):
    url = 'https://market.douban.com/book/?utm_campaign=book_nav_freyr&utm_source=douban&utm_medium=pc_web&page='\
          + str(page) + '&page_num=18&'
    html = get_page(url)
    for item in parse_page(html):
        print(item)
        write_to_file(item)


if __name__ == "__main__":
    for i in range(3):
        main(i+1)

最后的结果大概是这样

image.png
在整个实现过程中,个人遇到的主要问题如下

1)看懂网页结构,这里每一本新书的信息都包含在<li></li>标签里面,根据class等参数提取相应信息;
2)def函数中return和print的问题
比如
def test(num):
    print(num)


test(33)
print(test(33))

返回

image.png
此处返回了3个结果,前两个结果都是执行了函数test,
最后一个None是print(test(33))的结果,原因在于test函数可以运行,但是没有return任何值,pycharm也提示Function 'test' doesn't return anything
def test(num):
    return num


test(33)  
print(test(33))

返回

image.png
test函数返回num对象,将其打印输出。
3)和第2点也相关,yield函数的使用
一个带有 yield 的函数就是一个生成器,每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。
4)字符编码和数据类型问题
open.write()中内容参数必须为字符串,此处利用json.dumps()方法将字典转化为字符串,反之,将字符串转化成字典的函数是json.loads()。
其中json.dumps()中的参数ensure_ascii默认为True,利用ascii编码,同时需要设置txt文件的编码格式。

相关文章

网友评论

      本文标题:用requests和正则表达式爬取豆瓣新书的信息

      本文链接:https://www.haomeiwen.com/subject/joyydqtx.html