ECommerceCrawlersTouTiao详解(代码分析篇二)

ECommerceCrawlersTouTiao详解(代码分析篇二),第1张

ECommerceCrawlers/TouTiao详解(代码分析篇二)

2021SC@SDUSC

ECommerceCrawlers/TouTiao详解

文章目录
  • ECommerceCrawlers/TouTiao详解
  • 一、代码概况
    • 爬虫功能
    • 代码位置
    • 文件夹结构
  • 二、代码详解(接上一篇博客)
      • 爬虫代码分析
      • 评价与改进

一、代码概况 爬虫功能

在头条中搜索某个指定字段,并将搜索结果中所有的文章用csv格式存储。

代码位置

在项目中的位置:ECommerceCrawlers/TouTiao

gitee中的位置:https://gitee.com/AJay13/ECommerceCrawlers/tree/master/TouTiao

文件夹结构
├─TouTiao
│  ├─pictures
│  │  ├─JosephNest.jpg
│  │  └─mortaltiger.jpg
│  ├─README.md
│  └─toutiao.py

Toutiao:TouTiao爬虫的最上级目录名

pictures:图片目录,用于README.md引用,该目录下的两张图片是微信二维码

README.md:头条爬虫的说明文档

toutiao.py:爬虫代码(重点)

二、代码详解(接上一篇博客) 爬虫代码分析
# 这个方法用于获取搜索结果是name的所有文章的url
def get_article_urls(name):
    # 拼接网址,我们能很明显的看出,下面的网址是用来搜索的,搜索的内容是name的值
    decde = quote(name)
    referer = 'https://www.toutiao.com/search/?keyword='+decde
    # 着重说一下下面的offset,offset的中文意思是偏移量。
    # 在爬虫中,offset一般用于翻页,
    # 比如说在某个网页中,一页有20条链接,我们在第一页时,offset=0 (0*20),
    # 当我们要请求第二页的数据时,需要将offset置为20 (1*20),以此类推。
    # offset一般和limit一起使用
    # 下面的offset的值在循环中依次为0、20、40、60、80、100
    for offset in range(0, 120, 20):
        # params是GET请求的参数,用于给服务器发送数据的,也可以直接写在URL中,
        # 写在params中,用requests.get(url=url,params=params,headers=headers)的写法会更美观优雅一些。
        params = {
            'aid': 24,
            'app_name': 'web_search',
            'offset': offset,
            'format': 'json',
            'keyword': name,
            'autoload': 'true',
            'count': 20,
            'en_qc': 1,
            'cur_tab': 1,
            'from': 'search_tab',
            'pd': 'synthesis',
            'timestamp': timestamp
        }
        # headers 请求头,抓包获取即可,
        # ua.random用于生成随机UA,是最基本的反爬方法,这个在上边已经说过了,就不细说了。
        headers = {
            'cookie': 'tt_webid=6781305717874820616; WEATHER_CITY=%E5%8C%97%E4%BA%AC; tt_webid=6781305717874820616; s_v_web_id=59cfa658a89df645e8a82f1618a81bd0; __tasessionId=g8ptymp5v1579144106433',
            'user-agent': ua.random,
            'x-requested-with': 'XMLHttpRequest',
            'referer': referer,
        }
        # 用get请求获取返回结果,get中的proxies也是代理ip的参数,当你真正需要用到代理ip的时候自然会知道怎么用。
        html = requests.get(url=base_url, params=params,
                            headers=headers, proxies=proxies)
        # 将返回结果转化为json格式,并获取data参数,将所有的data合成为一个列表
        result = list(html.json().get('data'))
        # 下面这个循环用于解析上面的data列表,
        # 此处要注意,result是一个data的列表,data是json格式的,不能使用字典的方法取值,而是要使用get()方法
        for item in result:
            # 提取每篇文章的url
            article_url = item.get('article_url') 
            # 下面这行我测试了一下,今日头条返回的数据里的网址不一定能打开,
            # 一定是要包含'http://toutiao.com/'的打开才有内容,
            # 至于mp4和长度<100,没看出来是干啥用的。
            if article_url and len(article_url) < 100 and (".mp4" not in article_url) and "toutiao.com" in article_url:
                # 至于为什么要将/group/换成/a,是因为今日头条的重定向,具体的可以看下边的例子
                # 这是一条可以访问的url:http://toutiao.com/group/7016575740439249441/,
                # 当你将它在浏览器中打开时,他会重定向为 https://www.toutiao.com/a7016575740439249441/
                if '/group/' in article_url:
                    article_url = article_url.replace(
                        '/group/', '/a').replace('http://', 'https://www.')
                # 将获取到的url添加到article_url_list
                article_url_list.append(article_url)
                print(article_url)
# 这个方法用于控制发送请求和存储
def request_AND_storage(name):
    # 文件名赋值为 name+".csv" ,应该是要将搜索结果存到相对应名称的csv中
    filename = name+".csv"
    # 异常处理,网站的反爬机制或者异常响应都可能导致函数的异常,
    # 为了保证函数能够运行下去,一般会使用异常处理
    try:
        # 调用上面的方法获取url列表
        get_article_urls(name)
    except Exception as e:
        print(e)
    # 为什么要用selenium?我实在不理解
    browser = webdriver.Chrome()
    # 程序休眠2s
    time.sleep(2)
    # 下面开始一条条获取article_url_list中的每篇文章的具体内容
    for url in article_url_list:
        print(url)
        try:
            # 在浏览器中模拟访问文章的url
            browser.get(url)
            # 程序休眠1s
            time.sleep(1)
            # 今日头条改版面了,下面这个xpath已经不对了,
            # 目前要想获取整篇文章需要先搜索xpath://article,
            # 再将//article下的所有

节点的文字内容进行拼接,所有中的href提取。 text_res = browser.find_element_by_xpath( '//div[@]') # 下面的代码已经没用了 print(text_res) text_res = text_res.text print(text_res) # 上面的代码已经没用了 # 将文章内容存储到csv中,我还是不理解为什么要同时调pandas和csv两个库... with open(filename, 'a', encoding='utf-8') as f: writer = csv.writer(f) L = [name, text_res] writer.writerow(L) except: continue # 退出selenium的webdriver browser.close()

# 函数入口
if __name__ == '__main__':
    # 异常处理
    try:
        # 尝试搜索“武汉疫情”并保存
        request_AND_storage('武汉疫情')
        # 如果下边还有进行搜索的话,需要重置article_url_list,只搜索一条的话这句话就显得多此一举了,
        # 而且这句话应该写在finally里边,而不是在try和except里各写一遍。
        article_url_list = []
        #休眠10s
        time.sleep(10)
    except Exception as e:
        print(e)
        article_url_list = []
        time.sleep(1)
评价与改进

从整个逻辑上来看,作者在写这个今日头条的爬虫的时候逻辑还是比较清晰的,但是从库和函数的使用上来说,这位作者显然是不太熟练,以至于出现了调用不同的库去实现同一个功能的做法。

在此我还是要强调一下,爬虫的学习阶段尽量还是不要去用selenium,对理解HTTP协议几乎没有任何帮助。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5495970.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存