首页"/>
python爬取新浪新闻首页
话说大老王的妻子田朴珺否认与王石婚姻危机,且怒怼网友:吃饱了撑的。
王石
之后,大老王就成了热搜名人。
又成了名人
很多网友表示,怎么能这么说话呢?好歹你也是个“贵族”……
今天,我们不讨论这个。我们专题讲解使用Python如何在浩如烟海的新浪新闻中获取我们想要知道的人物的新闻,我们以获取大老王的新闻为例。本文只是探讨技术问题,如果你对于批量获取新浪新闻内容感兴趣,建议你坚持往下看,获取通过本文,你可以得到一个不错的工具。
获取新闻
前情概要
对于这个课题,我试了N多种方法,如果你只是爬取新闻,比如首页内展示的新闻,新浪没有进行反爬措施,或者说反爬措施相对容易破解。但是,如果你使用搜索功能的话,想要爬取搜索出来的内容,还是有一定难度的……
今天,我们手把手教你降低这一难度。
简单方法
刚开始的时候,我的思路是这样的,先进入新闻搜索页面,然后搜索“王石”,出现了下面的内容。
搜索王石后界面
可以看到,总共7页内容,有点少哦,刚开始页面才4篇新闻,之后的就是每页20篇新闻。(不好意思,发现一个bug,截止发文,文章总数并不是看到的132篇,其实只有116篇内容,大家自己验证吧)
思路
分析网址信息
网址信息
当我使用requests库时,获取第一页的信息正常,而第二页就没法获取了。其实页面是通过js代码控制的,每次点击页码后会出现相应的内容,如果使用修改网址传参的话从第二页开始一般都是得不到内容的。
因此,分析网页网址信息和内容应该是解决这类问题的重中之重。
那怎么办?
我们知道对于这类js加载页面的问题,有两个办法:一是利用Python中相关模块去执行js代码,这个网上很多教程,感兴趣的小伙伴可以参考学习下;再一个就是使用selenium或者PhantomJS等自动化模块模拟人打开一个网页,然后获取网页源代码(此时获取到的就是执行js后的代码),然后分析其中的内容。
怎么办呢?
思路
今天,我们着重使用第二个方法来将新浪新闻中关于王石的新闻做一整理。我们的思路是这样的,直接打开这个搜索页面,首先获取第一页内容并从中提取我们需要的信息;然后每次使用selenium单击下一页内容,获取下一页面的源代码及提取需要的信息。最终,将每一页面我们需要的信息通过一个列表返回。
准备环境
Python3.7 安装selenium、requests、bs4库
具体实现步骤
【获取单页面内容】
准备好,开始了
首先,设置UA代理
header = { 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36' }
这里的UA代理是爬虫的基础,大家可以自己构建一个UA代理池,这里不再赘述。
然后获取单页面内容,由于搜索网址的url是经过编码处理的,所以此处应该定一个网址处理函数
def parse_key(key):
return parse.quote(key, encoding='gb2312')
然后使用该函数即可获取到某一单页内容。
def get_text(key='王石'):
req = requests.get(url.format(parse_key(key)), headers=header).text
return req
这里没有进行异常处理,貌似也不需要了,大家可以自行加上去。
【使用selenium自动化处理】
自动化处理
定义一个函数,使用webdriver打开网址并返回webdriver对象,便于我们后续操作
def in_url(url):
wb = webdriver.Ie()
wb.get(url)
return wb
然后,我们单击一个页码时,将每一页的新闻内容展示并获取源代码。
def click_element(wb, el_no, total_no):
if el_no == 1:
e = wb.find_element_by_xpath('//*[@id="_function_code_page"]/a[1]')
e.click()
elif 1 < el_no and el_no < total_no:
e = wb.find_element_by_xpath('//*[@id="_function_code_page"]/a[{}]'.format(
el_no + 2))
e.click()
return wb.page_source
上面两步是重点,通过分析,我们知道,每次单击“下一页”时,xpath变化范围是页码+2(因为网页中加了“上一页”和“下一页”选项),el_no为1时,实际是我们单击获得第二页的内容。理解了上面的内容就好办了。
【使用BeautifulSoup库获取有效信息】
靓汤不错,你会烹饪吗
下面是我们定义的获取信息的函数,它可以从单页内容中搜索所有"h2"标签内容(里面含有新闻标题、作者、发文日期、新闻链接等内容),我们逐一从标签中将重点内容获取出来。
def find_info_bs4(html):
r_lst = []
soup = BeautifulSoup(html, 'html.parser')
for item in soup.find_all('h2'):
tmp_dict = {}
tmp_dict['title'] = item.find('a').text
print(tmp_dict['title'])
tmp_dict['author'] = item.find('span').text.split(' ')[0]
print(tmp_dict['author'])
tmp_dict['time'] = " ".join(item.find('span').text.split(' ')[1:])
print(tmp_dict['time'])
tmp_dict['url'] = item.find('a').get('href')
print(tmp_dict['url'])
r_lst.append(tmp_dict)
return r_lst
【整合流程】
整合资源
# 利用selenium进入网址
wb = in_url(url.format(parse_key('王石')))
# 最终结果
result_lst = []
print('第一页')
# 先将第一页新闻筛选添加到result_lst中
result_lst.extend(find_info_bs4(wb.page_source))
print('{}'.format(len(find_info_bs4(wb.page_source))))
# 获取总页面,多少个分页元素就有多少页
n = len(wb.find_elements_by_xpath('//*[@id="_function_code_page"]/a'))
# 循环遍历每一页面
for i in range(1, n):
print('第{}页'.format(i + 1))
# 单击后获取源代码
html = click_element(wb, i, n)
# 提取有效信息并将字典添加到result_lst中
result_lst.extend(find_info_bs4(html))
print('添加记录{}条'.format(len(find_info_bs4(html))))
# 打印最终新闻条数
print(len(result_lst))
执行结果展示
最终,获取到下面内容
程序运行结果展示
好了,今天的内容就到这里了。怎么样?是不是很酷?感兴趣的小朋友可以试试看,如果将关键字修改后,可以检索别的新闻内容。其实,可以将result_lst改为set数据类型。当然,你也可以将这些函数封装成一个类使用。可做更多的扩展,由你决定。
欢迎大家关注我,后续会推出更有意思的内容。
转载请注明出处,百家号:Python高手养成
更多推荐
python爬取新浪新闻首页
发布评论