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协议几乎没有任何帮助。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)