【爬虫项目】人民日报

爬虫目标

指定日期,爬取人民日报所有版面的新闻
mark

简要分析

版面链接分析

发现一共有20个版面,分别有 20 个链接,只是每个链接后的数字不同

http://paper.people.com.cn/rmrb/html/2020-03/12/nbs.D110000renmrb_01.htm

爬虫结构

用到模块:requests、BeautifulSoup、gevent

构造参数类

需要下载其他日期,自行修改就好

class TOOL():
    # 年月 yyyy-mm 格式
    date = "2020-03"

    # 日期
    day = "12"

    # 新闻详情页
    text_url = "http://paper.people.com.cn/rmrb/html/{}/{}/".format(date,day)

    # 版面 URL 列表
    @classmethod
    def get_urls(cls):
        urls = list() # 链接列表
        for num in range(1,20):
            # 10 以下数字补 0
            if 1 <= num < 10 :
                num = "0" + str(num)
            urls.append("http://paper.people.com.cn/rmrb/html/{}/{}/nbs.D110000renmrb_{}.htm".format(cls.date,cls.day,num))
        return urls

获取新闻页链接

获取一个版面的新闻链接

def get_layout_url(url):
"""
返回值:[{"layout":layout,"href":href},{"layout":layout,"href":href},...]
"""
    print(url)
    r = requests.get(url=url)
    r.encoding = r.apparent_encoding

    # 解析网页获取 版面名称、文章链接
    soup = BeautifulSoup(r.text ,"html.parser")
    list_l_soup = soup.find(name="div",attrs={"class":"list_l"})
    # 获取版面名
    layout = list_l_soup.find_next(name="div",attrs={"class":"l_t"}).string.strip()
    print(layout)
    ul_soup = list_l_soup.find_next(name="div",attrs={"id":"titleList"}).find_next(name="ul")
    li_soup = ul_soup.find_all(name="li")
    # 返回值列表
    href_titles = list()
    for href_title_tag in li_soup:
        # 获取 href
        href = TOOL.text_url + href_title_tag.find(name="a")["href"]
        print(href)
        # 结果组合
        href_titles.append({"layout":layout,"href":href})
    return href_titles

下载新闻并保存

提前创建好rb/ 目录

def download(href_titles):
    for href_title in href_titles:
        # 获取新闻页
        r = requests.get(url=href_title.get("href"))
        r.encoding =r.apparent_encoding
        # 解析新闻页
        soup = BeautifulSoup(r.text ,"html.parser")
        soup_text = soup.find(name="div",attrs={"class":"text_c"})

        # 文章标题
        title = soup_text.h1.string
        print(title)
        # 正文
        main_sc= soup_text.find_next(name="div",attrs={"id":"ozoom"})
        # 正文里有一段 script 的注释,对结果有影响,需要替换掉
        main_sc.find_next(name="script",attrs={"language":"javascript"}).string = " "
        main_text = main_sc.get_text().strip()
        # 写入文件
        with open("rb/"+title+".txt","w+",encoding="utf-8") as file:
            file.write(main_text)

主逻辑

if __name__ == '__main__':
    # 通过for循环获取所有新闻链接,组成列表
    href_titles = [get_layout_url(url) for url in TOOL.get_urls()]

    # 添加协程队列并下载
    layout_url_list = [gevent.spawn(download,href_title) for href_title in href_titles]
    gevent.joinall(layout_url_list)

mark

发表评论 / Comment

用心评论~