炼数成金 门户 大数据 Python 查看内容

出门旅行没规划?python抓取马蜂窝自由行攻略!

2018-2-1 14:40| 发布者: 炼数成金_小数| 查看: 22904| 评论: 0|原作者: 渲染奢华|来自: 知乎

摘要: 对于新手来讲写爬虫最重要的一点就是要确定目标,知道自己要抓什么!今天的目标是马蜂窝北京自由行攻略,有了目标咱们就开始干吧!1.分析马蜂窝的url,列表页翻页url没变化,查看html 翻页链接里还没路径,当时看了 ...

tm 存储 Java HTML Hadoop 培训

本来想搞个简单的网站没去搞携程啥的抓个马蜂窝玩玩,没想到马蜂窝也不是那么容易搞

对于新手来讲写爬虫最重要的一点就是要确定目标,知道自己要抓什么!

身为小白学完爬虫基础就想找东西练手,结果满脑子想到的都是一些大网站 京东,淘宝,携程等等········

难的自己还搞不定,小网站还没意思,我也很无奈 (有木有大佬推荐下好玩的网站我好练练手)

今天的目标是马蜂窝北京自由行攻略,有了目标咱们就开始干吧!

1.分析马蜂窝的url,列表页翻页url没变化,查看html 翻页链接里还没路径,当时看了想吐血噗····


2.无奈抓包慢慢找其他接口,找到了json接口里面存着html,就一个参数也很好分析

3.然后就简单了循环发请求拿标题链接去解析详情页

4.详情页的内容是放在不同div下 还要循环把所有内容抓到再拼接成一个字符串,稍微麻烦点

5.测试的时候发现有的文章是没作者没简介的,要判断一下如果抓到空 作者就赋值个'匿名'

6.存储的时候我用标题做的文件名TXT格式,又出现文件名有非法字符串的错误,百度了一段代码,贼鸡儿好用!

res = r"[\/\\\:\*\?\"\<\>\|]"

title = re.sub(res, "_", title)

最后上代码:
import requests
from bs4 import BeautifulSoup
import json
import re
import os


headers = {
    "Host" : "www.mafengwo.cn",
    "Connection" : "keep-alive",
    "Pragma" : "no-cache",
    "Cache-Control" : "no-cache",
    "Accept" : "*/*",
    "X-Requested-With" : "XMLHttpRequest",
    "User-Agent" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.78 Safari/537.36",
    "Referer" : "http://www.mafengwo.cn/gonglve/ziyouxing/mdd_10065/",
    "Accept-Language" : "en,zh-CN;q=0.8,zh;q=0.6",
}
#发送请求
def getpage():
    os.mkdir('./mafengwo')
    base_url = 'http://www.mafengwo.cn/gonglve/ziyouxing/list/list_page?mddid=10065&page=1'
    response = requests.get(base_url,headers=headers)
    json_html = json.loads(response.text)
    #提取html内容
    html = json_html["html"]
    # print(html)
    html = BeautifulSoup(html,'lxml')
    #获取较大页数
    max_page = html.select('span.count')[0].text
    #用正则把页数从字符串中抽取出来
    pattern = re.compile(r'\d+')
    res = pattern.search(max_page)
    max_number = res.group()
    #循环发送请求获取所有列表页
    for i in range(1,int(max_number)+1):
        base_url = 'http://www.mafengwo.cn/gonglve/ziyouxing/list/list_page?mddid=10065&page=%d'
        response = requests.get(base_url % i,headers=headers)
        print('正在抓取第%s页' % i)
        json_html = json.loads(response.text)
        html = json_html["html"]
        html = BeautifulSoup(html, 'lxml')
        #获取详情页链接
        list_link = html.select('a._j_item')
        for link in list_link:
            info = link.get('href')
            #网页用的相对路径所以要拼接一下
            info_link = 'http://www.mafengwo.cn' + info
            # print(info_link)
            details_page(info_link)

# 解析详情页
def details_page(info_link):
    response = requests.get(info_link,headers=headers)
    html = BeautifulSoup(response.text,'lxml')
    title = html.select('div.l-topic h1')[0].text  #标题
    name = html.select('span.name')  #作者
    #作者有的是空的 要判断一下
    if name == []:
        name = '匿名'
    else:
        name = name[0].text.strip()
    brief = html.select('div.l-topic > p') #简介
    if brief == []:
        brief = '无简介'
    else:
        brief = brief[0].text.strip()
    content_list = html.select('div.f-block')  #内容列表
    #加换行为了好看而已
    text = ['\n']
    #循环内容列表把左右空格去掉 再用换行拼接成字符串
    for i in content_list:
        centent = i.text.strip() #获取内容文字
        text.append(centent)
    content_text = '\n'.join(text)
    img_list = html.select('img._j_lazyload') #图片列表
    img = ['\n']
    for n in img_list:
        src = n.get('data-rt-src') #获取图片路径
        img.append(src)
    img_src = '\n'.join(img)
    #去除名字中的非法字符
    res = r"[\/\\\:\*\?\"\<\>\|]"  # '/ \ : * ? " < > |'
    title = re.sub(res, "_", title)  # 替换为下划线
    # print(title,name,brief,content_text,img_src)
    item = {
        'title': title,
        'name': name,
        'brief': '\n'+ brief,
        'content_text': content_text,
        'img_src': img_src,
    }
    storage(item)
#存储函数
def storage(item):

    # 以文章标题命名存成TXT
    with open('./mafengwo/' + item['title'] + '.txt','w',encoding = 'utf-8') as f:
        txt_list = []
        txt_list.append(''.join([item['title'], item['name'],item['brief'],item['content_text'],item['img_src']]))
        f.writelines(txt_list)

if __name__ == '__main__':
    getpage()


欢迎加入本站公开兴趣群
软件开发技术群
兴趣范围包括:Java,C/C++,Python,PHP,Ruby,shell等各种语言开发经验交流,各种框架使用,外包项目机会,学习、培训、跳槽等交流
QQ群:26931708

Hadoop源代码研究群
兴趣范围包括:Hadoop源代码解读,改进,优化,分布式系统场景定制,与Hadoop有关的各种开源项目,总之就是玩转Hadoop
QQ群:288410967

鲜花

握手

雷人

路过

鸡蛋

相关阅读

最新评论

热门频道

  • 大数据
  • 商业智能
  • 量化投资
  • 科学探索
  • 创业

即将开课

 

GMT+8, 2018-10-19 13:03 , Processed in 0.142206 second(s), 24 queries .