最近学了一段时间的Python,想写个爬虫,去网上找了找,然后参考了一下自己写了一个爬取给定页面的爬虫。
Python的第三方库特别强大,提供了两个比较强大的库,一个requests, 另外一个BeautifulSoup,这两个库目前只是会用,其他的还不太了解,网上给了一个BeautifulSoup文档的链接,特别方便,不会的直接查(中文版的),还有一个关于requests的。
在使用这些第三方库之前要导入
import requests from bs4 import BeautifulSoup
写这个爬虫首先要获得该网页的html代码,然后用BeautifulSoup库进行解析,然后再分析一下腾讯新闻的html结构
这个是获取网页的html,为了方便使用,将它封装成一个函数
def getHTMLText(url): try: r = requests.get(url, timeout = 30) r.raise_for_status() #r.encoding = 'utf-8' return r.text except: return ""
其中,raise_for_status()方法在非成功时产生一个异常,即只要返回的请求代码状态status_code不是200,就产生一个异常
现在分析一下腾讯新闻的html结构
在chrome浏览器下,直接进去新闻之后,右键题目检查就可以定位到题目所在的html代码,如下图
然后会看到<h1>标签内,它的上一级标签是div,并且class="hd",BeautifulSoup提供了一个CSS选择器,直接调用select方法即可,具体怎么用请查看文档,文档部分如图:
所以代码就可以写
def getContent(url): html = getHTMLText(url) # print(html) soup = BeautifulSoup(html, "html.parser") title = soup.select("div.hd > h1") print(title[0].get_text()) time = soup.select("div.a_Info > span.a_time") print(time[0].string) author = soup.select("div.qq_articleFt > div.qq_toolWrap > div.qq_editor") print(author[0].get_text()) paras = soup.select("div.Cnt-Main-Article-QQ > p.text") for para in paras: if len(para) > 0: print(para.get_text()) print()
其中select返回的是一个列表,所以打印的时候要有下标元素,由于段落是有多个段,所以要用for循环把他们依次取出来
关于select的用法,还是文档讲的比较详细
完整代码如下(爬取http://news.qq.com/a/20170504/012032.htm网页新闻,并保存到文件中)
#此代码主要是从给定腾讯新闻网页中爬取新闻的题目,时间,正文,作者 import requests from bs4 import BeautifulSoup def getHTMLText(url): try: r = requests.get(url, timeout = 30) r.raise_for_status() #r.encoding = 'utf-8' return r.text except: return "" def getContent(url): html = getHTMLText(url) # print(html) soup = BeautifulSoup(html, "html.parser") title = soup.select("div.hd > h1") print(title[0].get_text()) time = soup.select("div.a_Info > span.a_time") print(time[0].string) author = soup.select("div.qq_articleFt > div.qq_toolWrap > div.qq_editor") print(author[0].get_text()) paras = soup.select("div.Cnt-Main-Article-QQ > p.text") for para in paras: if len(para) > 0: print(para.get_text()) print() #写入文件 fo = open("text.txt", "w+") fo.writelines(title[0].get_text() + " ") fo.writelines(time[0].get_text() + " ") for para in paras: if len(para) > 0: fo.writelines(para.get_text() + " ") fo.writelines(author[0].get_text() + ' ') fo.close() #将爬取到的文章用字典格式来存 article = { 'Title' : title[0].get_text(), 'Time' : time[0].get_text(), 'Paragraph' : paras, 'Author' : author[0].get_text() } print(article) def main(): url = "http://news.qq.com/a/20170504/012032.htm" getContent(url); main()