初次學習爬蟲技術,在知乎上看了如何爬去糗事百科的段子,因而打算本身也作一個。html
實現目標:1,爬取到糗事百科的段子python
2,實現每次爬去一個段子,每按一次回車爬取到下一頁正則表達式
技術實現:基於python的實現,利用Requests庫,re庫,bs4庫的BeautifulSoup方法來實現的app
主要內容:首先咱們要理清一下爬取實現的思路,咱們來構建一下主體框架。第一步咱們先寫一個利用Requests庫來獲取網頁的方法,第二步咱們利用bs4庫的BeautifulSoup方法來分析所獲取的網頁信息並利用正則表達式來匹配相關的段子信息。第三步咱們來打印出得到的信息。以上方法咱們都經過一個主函數來進行執行。框架
一,首先導入相關的庫函數
import requests
from bs4 import BeautifulSoup
import bs4
import re
二,首先進行網頁信息的獲取學習
def getHTMLText(url):
try:
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = {'User-Agent': user_agent}
r = requests.get(url,headers = headers)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return ""
三,把信息放到r後再進行解析 優化
soup = BeautifulSoup(html,"html.parser")
咱們須要的是段子的內容和發佈人,經過網頁的查看源代碼咱們知道段子的發佈人在:url
'div', attrs={'class': 'content'}中
段子的內容在spa
'div', attrs={'class': 'author clearfix'}中
因此咱們經過bs4庫的方法來提取這兩個標籤的具體內容
def fillUnivlist(lis,li,html,count):
soup = BeautifulSoup(html,"html.parser")
try:
a = soup.find_all('div', attrs={'class': 'content'})
ll = soup.find_all('div', attrs={'class': 'author clearfix'})
而後經過具體到正則表達式來獲取信息
for sp in a:
patten = re.compile(r'<span>(.*?)</span>',re.S)
Info = re.findall(patten,str(sp))
lis.append(Info)
count = count + 1
for mc in ll:
namePatten = re.compile(r'<h2>(.*?)</h2>', re.S)
d = re.findall(namePatten, str(mc))
li.append(d)
咱們須要注意的是使用find_all以及re的findall方法返回的都是一個列表,使用正則表達式時咱們只是粗略提取並無把標籤中的換行符去掉
接下來咱們只須要把2個列表的內容進行組合輸出就能夠了
def printUnivlist(lis,li,count):
for i in range(count):
a = li[i][0]
b = lis[i][0]
print ("%s:"%a+"%s"%b)
而後我作一個輸入控制函數,輸入Q返回錯誤,退出,輸入回車返回正確,進行下一頁段子的加載
def input_enter():
input1 = input()
if input1 == 'Q':
return False
else:
return True
咱們經過主函數來實現所輸入的控制,若是控制函數返回的是錯誤就不執行輸出,若是返回的是正確就繼續輸出。咱們經過一個for循環來進行加載下一頁。
def main():
passage = 0
enable = True
for i in range(20):
mc = input_enter()
if mc==True:
lit = []
li = []
count = 0
passage = passage + 1
qbpassage = passage
print(qbpassage)
url = 'http://www.qiushibaike.com/8hr/page/' + str(qbpassage) + '/?s=4966318'
a = getHTMLText(url)
fillUnivlist(lit, li, a, count)
number = fillUnivlist(lit, li, a, count)
printUnivlist(lit, li, number)
else:
break
這裏咱們須要注意到是每一次for循環都會刷新一次lis【】和li【】,這樣每次均可以正確輸出該網頁的段子內容
一下爲源代碼:
import requests
from bs4 import BeautifulSoup
import bs4
import re
def getHTMLText(url):
try:
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = {'User-Agent': user_agent}
r = requests.get(url,headers = headers)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return ""
def fillUnivlist(lis,li,html,count):
soup = BeautifulSoup(html,"html.parser")
try:
a = soup.find_all('div', attrs={'class': 'content'})
ll = soup.find_all('div', attrs={'class': 'author clearfix'})
for sp in a:
patten = re.compile(r'<span>(.*?)</span>',re.S)
Info = re.findall(patten,str(sp))
lis.append(Info)
count = count + 1
for mc in ll:
namePatten = re.compile(r'<h2>(.*?)</h2>', re.S)
d = re.findall(namePatten, str(mc))
li.append(d)
except:
return ""
return count
def printUnivlist(lis,li,count):
for i in range(count):
a = li[i][0]
b = lis[i][0]
print ("%s:"%a+"%s"%b)
def input_enter():
input1 = input()
if input1 == 'Q':
return False
else:
return True
def main():
passage = 0
enable = True
for i in range(20):
mc = input_enter()
if mc==True:
lit = []
li = []
count = 0
passage = passage + 1
qbpassage = passage
print(qbpassage)
url = 'http://www.qiushibaike.com/8hr/page/' + str(qbpassage) + '/?s=4966318'
a = getHTMLText(url)
fillUnivlist(lit, li, a, count)
number = fillUnivlist(lit, li, a, count)
printUnivlist(lit, li, number)
else:
break
main()
第一次作仍是有不少能夠優化的地方但願你們能夠指出來。