抓取愛問知識人問題,保存至數據庫。

新手上路,歡迎批評。博客暫時只爲記錄學習過程。

抓取結果:

整體思路:

1.鏈接數據庫並建好一張表。要存儲以下信息,問題,回答者,回答時間,回答內容。

def createtable():
	# 打開數據庫連接
	db = pymysql.connect("localhost","root","sql123","likelearn", charset='utf8' )
	# 使用 cursor() 方法創建一個遊標對象 cursor
	cursor = db.cursor()
	# 使用 execute() 方法執行 SQL,如果表存在則刪除
	cursor.execute("DROP TABLE IF EXISTS goodAnswer")
	# 使用預處理語句創建表
	sql = """CREATE TABLE goodAnswer(
         question text not null,
         a_name varchar(20) not null,
         a_time varchar(20) not null,
         a_content text not null) CHARSET=utf8 """
	cursor.execute(sql)
    # 關閉數據庫連接
	db.close()

2.抓取一個問題彙總頁面  http://iask.sina.com.cn/c/74-goodAnswer-1-new.html   寫一個函數geturls()獲取該頁面上指向其他問題彙總頁面的鏈接,存儲在全局變量 pageurls 中。

註釋掉的最後一行,是遞歸抓取整個100頁的所有問題彙總頁面的鏈接,這裏我只抓取了1,2,3,100這四個頁面。

def geturls(url):
	global pageurls
	url = "http://iask.sina.com.cn/" + str(url)
	print(url)
	req = getpage(url)
	soup = BeautifulSoup(req.text,"html.parser")
	hrefs = soup.find("div",{"class":"page mt30"}).find_all("a")
	for pageurl in hrefs:
		if "href" in pageurl.attrs:
			if pageurl["href"] not in pageurls:
				pageurls.append(pageurl["href"])
				# geturls(pageurl["href"])

 3.兩層循環,第一層循環變量pageurls,每次獲得一個問題彙總頁面,並且用函數 getlinks() 獲得該頁面上的所有具體問題的鏈接。

                         第二層抓取具體問題回答的頁面,並且用函數 getdetail() 獲得最好回答的的各個字段。

# 獲取頁面的所有問題鏈接
def getlinks(soup):
	temp = soup.find_all("div",{"class":"question-title"})
	links = []
	for link in temp:
		links.append(link.a["href"])
	return links
 
# 獲取問題的回答者,回答時間回答內容 
def getdetail(soup):
	item = []
	#獲取回答者的名字
	a_name = soup.find("div", {"class":"answer_tip"})
	if a_name == None:
		a_name = " "
	else:
		a_name = a_name.a
	#獲取回答時間
	a_time = soup.find("div", {"class":"answer_tip"})
	if a_time == None:
		a_time = " "
	else:
		a_time = a_time.span
    #獲取回答內容
	a_content = soup.find("div",{"class":"answer_text"})
	if a_content == None:
		a_content = " "
	elif soup.find("div",{"class":"answer_text"}).find("div",{"style":"display: none"}) == None:
		a_content = soup.find("div",{"class":"answer_text"})
	else:
		a_content = soup.find("div",{"class":"answer_text"}).find("div",{"style":"display: none"})
	ques = soup.find("div", {"class":"question_text"})
	item.append(tool(ques))
	item.append(tool(a_name) )
	item.append(tool(a_time) )
	item.append(tool(a_content) )
	return item
 4. 鏈接數據庫,將抓取到的各個字段存儲在已經建好的表 goodAnswer 中。

插入方法參考:   http://www.runoob.com/python3/python3-mysql.html

以下是全部代碼:

# -*- coding:utf-8 -*-
import requests
from bs4 import BeautifulSoup
import re
import pymysql
import time
# 用來存儲頁面的url
pageurls = []

# 獲取一個頁面
def getpage(url):
	headers = {'user-agent':  'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'}
	req = requests.get(url, headers = headers)
	if req.status_code == 200:
		pass
	else:
		print("獲取失敗,請檢查URL:", url)
	return req

# 獲取頁面的所有問題鏈接
def getlinks(soup):
	temp = soup.find_all("div",{"class":"question-title"})
	links = []
	for link in temp:
		links.append(link.a["href"])
	return links

# 獲取所有的頁面鏈接
def geturls(url):
	global pageurls
	url = "http://iask.sina.com.cn/" + str(url)
	print(url)
	req = getpage(url)
	soup = BeautifulSoup(req.text,"html.parser")
	hrefs = soup.find("div",{"class":"page mt30"}).find_all("a")
	for pageurl in hrefs:
		if "href" in pageurl.attrs:
			if pageurl["href"] not in pageurls:
				pageurls.append(pageurl["href"])
				# geturls(pageurl["href"])

# 獲取問題的回答者,回答時間回答內容 
def getdetail(soup):
	item = []
	#獲取回答者的名字
	a_name = soup.find("div", {"class":"answer_tip"})
	if a_name == None:
		a_name = " "
	else:
		a_name = a_name.a
	#獲取回答時間
	a_time = soup.find("div", {"class":"answer_tip"})
	if a_time == None:
		a_time = " "
	else:
		a_time = a_time.span
    #獲取回答內容
	a_content = soup.find("div",{"class":"answer_text"})
	if a_content == None:
		a_content = " "
	elif soup.find("div",{"class":"answer_text"}).find("div",{"style":"display: none"}) == None:
		a_content = soup.find("div",{"class":"answer_text"})
	else:
		a_content = soup.find("div",{"class":"answer_text"}).find("div",{"style":"display: none"})
	ques = soup.find("div", {"class":"question_text"})
	item.append(tool(ques))
	item.append(tool(a_name) )
	item.append(tool(a_time) )
	item.append(tool(a_content) )
	return item

# 清理不必要的標籤和特殊符號
def tool(x):
	x = str(x)
	replaceBR = re.compile('<pre>|</pre>')
	removeImg = re.compile('<span.*?>|</span>" "*?|</span>')
	replaceLine = re.compile('<div.*?>|</div>')
	removeAddr = re.compile('<a.*?>|</a>')
	removespace = re.compile('\s*')
	removete = re.compile('\W')
	x = re.sub(replaceBR,"",x)
	x = re.sub(removeImg,"",x)
	x = re.sub(replaceLine,"",x)
	x = re.sub(removeAddr,"",x)
	x = re.sub(removespace,"",x)
	x = re.sub(removete,"",x)
	return x

def createtable():
	# 打開數據庫連接
	db = pymysql.connect("localhost","root","sql123","likelearn", charset='utf8' )
	# 使用 cursor() 方法創建一個遊標對象 cursor
	cursor = db.cursor()
	# 使用 execute() 方法執行 SQL,如果表存在則刪除
	cursor.execute("DROP TABLE IF EXISTS goodAnswer")
	# 使用預處理語句創建表
	sql = """CREATE TABLE goodAnswer(
         question text not null,
         a_name varchar(20) not null,
         a_time varchar(20) not null,
         a_content text not null) CHARSET=utf8 """
	cursor.execute(sql)
    # 關閉數據庫連接
	db.close()

# 邏輯控制主函數
def main():
    # 鏈接數據庫操作數據庫
	db = pymysql.connect("localhost","root","sql123","likelearn", charset='utf8')
	# 使用 cursor() 方法創建一個遊標對象 cursor
	cursor = db.cursor()

	# 爲了簡潔我只抓取第 1 2 3 100 這四個頁面的 url
	geturls("/c/74-goodAnswer-1-new.html") 
	# 遍歷四個 url 抓取頁面
	for url in pageurls:
		page = getpage("http://iask.sina.com.cn" + str(url))
		soup = BeautifulSoup(page.text,"html.parser")
		print("獲得該頁面所有問題的鏈接", "http://iask.sina.com.cn" + str(url)) 
		links = getlinks(soup)
		# 遍歷每個該頁面的所有問題鏈接
		for link in links:
			print("獲得goodAnswer頁面詳情",link) 
			a_page = getpage("http://iask.sina.com.cn/" + str(link))
			a_soup = BeautifulSoup(a_page.text, "html.parser")
			print("獲得問題最好回答的各個信息段") 
			a_item = getdetail(a_soup)
			# #SQL 插入語句
			sql = "INSERT INTO goodAnswer(question, a_name, a_time, a_content)VALUES ('%s', '%s',  '%s', '%s')"%(a_item[0], a_item[1], a_item[2],a_item[3])
			try:
				print("# 執行 sql 語句")
				cursor.execute(sql)
				print("# 提交到數據庫執行") 
				db.commit()
			except:
				print("# 發生錯誤回滾") 
				db.rollback()
			time.sleep(2)
	# 關閉數據庫連接
	db.close()
createtable()
main()



發佈了38 篇原創文章 · 獲贊 15 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章