日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python360百科_python抓取360百科踩过的坑!

發布時間:2024/9/19 python 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python360百科_python抓取360百科踩过的坑! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

學習python一周,學著寫了一個爬蟲,用來抓取360百科的詞條,在這個過程中。因為一個小小的修改,程序出現一些問題,又花了幾天時間研究,問了各路高手,都沒解決,終于還是自己攻克了,事實上就是對list列表理解不夠深入導致的。這個bug非常有借鑒意義,分享出現。

先看看終于抓取出的結果:

以下進入正題。先來看看文件結構。這里有5個模塊:

spider_main.py是入口函數

url_manager.py是管理器,管理須要抓取的url和已經抓取的url

html_downloader.py是下載器,下載相應url的網頁

html_parser.py是解析器,解析出新的url列表和當前的詞條信息

html_outputer.py是輸出器。將抓取的詞條title和解釋summary輸出成一個html表格

本程序使用的是最新的python3.4.4。使用的類庫有:

官方的urllib

第三方的BeautifulSoup(自行下載安裝)

一、spider_main.py

這個函數是入口函數,全部方法都是字面意思,能夠到相應的類中查看

from baike360_spider import url_manager, html_downloader, html_parser, html_outputer

class SpiderMain(object):

def __init__(self):

self.urls = url_manager.UrlManager()

self.downloader = html_downloader.HtmlDownloader()

self.parser = html_parser.HtmlParser()

self.outputer = html_outputer.HtmlOutputer()

def craw(self):

count = 1

self.urls.add_new_url(root_url)

while self.urls.has_new_url():

try:

new_url = self.urls.get_new_url()

print(‘craw %d: %s‘ % (count, new_url))

html_cont = self.downloader.download(new_url)

new_urls, new_data = self.parser.parse(new_url, html_cont)

self.urls.add_new_urls(new_urls)

self.outputer.collect_data(new_data)

if count == 5:

break

count += 1

except Exception as e:

print(‘craw failed‘)

print(e)

self.outputer.output_html()

if __name__ == ‘__main__‘:

root_url = ‘http://baike.so.com/doc/1790119-1892991.html‘

obj_spider = SpiderMain()

obj_spider.craw()

二、url_manager.py

管理器的作用是處理新的須要抓取的url和已經抓取的url,因此在構造函數里面初始化兩個變量,相應有4個方法,功能都非常easy,看看就懂。

class UrlManager(object):

def __init__(self):

self.new_urls = set()

self.old_urls = set()

def add_new_url(self, url):

if url is None:

return

if url not in self.new_urls and url not in self.old_urls:

self.new_urls.add(url)

def add_new_urls(self, urls):

if urls is None or len(urls) == 0:

return

for url in urls:

self.add_new_url(url)

def has_new_url(self):

return len(self.new_urls) != 0

def get_new_url(self):

new_url = self.new_urls.pop()

self.old_urls.add(new_url)

return new_url

三、html_downloader.py

把相應的url網頁下載下來,準備給解析器解析須要的數據

import urllib.request

class HtmlDownloader(object):

def download(self, url):

if url is None:

return

res = urllib.request.urlopen(url)

if res.getcode() != 200:

return

return res.read()

四、html_parser.py

解析器的作用是對傳入的url和html網頁進行解析。使用到BeautifulSoup第三方庫,相應有兩個私有方法,一個解析出該網頁下全部的鏈接。存到list中,方便下次隨機抽取。還有一個解析出當前網頁詞條的title和summary,放到一個字典中。里面有3個key:url、title和summary。

在這個類里面踩了一個大坑,最后再講!

import re

from urllib.parse import urljoin

from bs4 import BeautifulSoup

class HtmlParser(object):

def __init__(self):

self.new_urls = set()

# self.res_data = dict()

def _get_new_urls(self, page_url, soup):

# new_urls = set()

# /doc/5912108-6125016.html或/doc/3745498.html

links = soup.find_all(‘a‘, href=re.compile(r‘/doc/[\d-]+\.html‘))

for link in links:

new_url = link[‘href‘]

new_full_url = urljoin(page_url, new_url)

# print(new_full_url)

self.new_urls.add(new_full_url)

return self.new_urls

def _get_new_data(self, page_url, soup):

res_data = dict()

# url

res_data[‘url‘] = page_url

# Python

title_node = soup.find(‘span‘, class_=‘title‘)

res_data[‘title‘] = title_node.get_text()

#

summary_node = soup.find(‘div‘, class_=‘card_content‘).find(‘p‘)

res_data[‘summary‘] = summary_node.get_text()

# print("dd: ", self.res_data)

return res_data

def parse(self, page_url, html_cont):

if page_url is None or html_cont is None:

return

soup = BeautifulSoup(html_cont, ‘html.parser‘, from_encoding=‘utf-8‘)

new_urls = self._get_new_urls(page_url, soup)

new_data = self._get_new_data(page_url, soup)

return new_urls, new_data

五、html_outputer.py

輸出器的作用是把解析器解析出的網頁字典存入列表。然后循環輸出一個html表格

class HtmlOutputer(object):

def __init__(self):

self.datas = []

def collect_data(self, data):

if data is None:

return

self.datas.append(data)

def output_html(self):

fout = open(‘output.html‘, ‘w‘, encoding=‘utf-8‘)

fout.write(‘‘)

fout.write("

")

fout.write(‘

‘)

fout.write(‘

for data in self.datas:

fout.write(‘

‘)

fout.write(‘

%s‘ % (data[‘url‘], data[‘title‘]))

fout.write(‘

%s‘ % data[‘summary‘])

fout.write(‘

‘)

fout.write(‘

‘)

fout.write(‘‘)

fout.write(‘‘)

fout.close()

六、*****關鍵。我踩過的坑!

!!!

我把解析器里面的res_data字典的初始化放到了構造函數里面,造成的結果是輸出的表格是5個反復的數據,都是和最后一組一樣。!

喜歡思考的同學能夠想想是為什么?

原因分析:

這要涉及到list列表和字典的性質了

首先,字典的key相應的value是不可變的,假設強行又一次賦值,會覆蓋上次的數據!

①第1次抓取后,res_data指向了字典{‘a‘: 1}

②res_data傳入輸出器后,self.datas列表內容也指向了字典{‘a‘: 1}

③第2次抓取后,解析器里面對a又一次賦新值2了,此時事實上是res_data指向了新的字典{‘a‘:

2}。因為原指向的key一樣,也一起變成了字典{‘a‘: 2},此時事實上self.datas列表的指向也變成了原字典{‘a‘:

2}(假設你在入口函數斷點查看,會出現一個奇葩的事。就是執行完解析器,可是還沒執行輸出器時,輸出器的self.datas已經變成和新解析出的值一樣了。!。當時我糾結了幾天)

④當res_data再次傳入輸出器后,會被加入后self.datas列表后面,因為原來里面的字典已經變成了{‘a‘:

2},全部此時會出現2個{‘a‘: 2},即

?

?self.datas = [{‘a‘: 2},?{‘a‘: 2}]

⑤如此循環抓取5次,終于self.datas里面是5個一樣的字典。并且都和最后一次抓取的一樣!

那么你可能會問,為什么把res_data初始化放在私有方法_get_new_data里面就沒問題呢?因為初始化在這里,每實例化一次解析器,就又一次執行一次這個函數。也會清空res_data字典,因此和原來指向的字典斷開了,又一次賦值也不會影響到原來的字典了。

總結

以上是生活随笔為你收集整理的python360百科_python抓取360百科踩过的坑!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲免费自拍 | 亚洲国产精品综合久久久 | 国产精品无码久久久久一区二区 | 精品人妻一区二区三区四区 | 国语精品 | 包射屋| 国产精品一区二区三区免费在线观看 | 第一色网站 | 中文字幕在线亚洲 | 先锋资源国产 | 中文字幕免费在线观看视频 | 亚洲无吗视频 | 国产一区二区三区视频网站 | 日韩五十路 | 最近中文字幕在线 | 国产真实的和子乱拍在线观看 | 国语毛片 | 亚洲精品20p | 97福利视频 | 亚洲天堂欧美 | 久久看看| 国产免费一区二区 | 一本综合久久 | 中文字幕国产日韩 | 男女爱爱网站 | 日韩在线一区视频 | 日韩精品久久久 | 精品中文字幕在线播放 | 精品xxxx| 亚洲国产专区 | 黄色大片aa | 亚洲成人午夜电影 | 污污视频网站在线免费观看 | 麻豆亚洲av熟女国产一区二 | 亚洲图片激情小说 | 日b视频在线观看 | 久久久精品麻豆 | 成人a√| 在线视频 一区二区 | 白丝少妇 | 国产日韩欧美不卡 | 午夜看片福利 | 男人添女人囗交视频 | 无码人妻aⅴ一区二区三区有奶水 | 97人妻精品一区二区三区视频 | 一级香蕉视频在线观看 | 国产一av| 久久久久久久久久久av | 国产精品视频麻豆 | 国产伦精品一区二区三区四区视频 | 国产传媒国产传媒 | 久久久毛片 | 女人18毛片毛片毛片毛片区二 | 国产av无码专区亚洲av麻豆 | a级免费视频 | 国产二级一片内射视频播放 | 精品一区在线看 | 蜜臀av午夜精品 | 欧美福利在线观看 | а√天堂8资源在线官网 | 国产婷| 大尺度av | 黄色xxxxxx| 国产精品无遮挡 | 日韩欧美精品一区二区 | 福利网址在线观看 | 韩日一级片 | 欧美成人自拍 | 综合视频在线 | 久久av综合网 | 黄色免费网站在线观看 | 一级黄色大片免费看 | 3d动漫精品啪啪一区二区免费 | 欧美亚洲一区二区三区四区 | 9l视频自拍蝌蚪9l视频 | 不卡一区在线观看 | 午夜免费福利网站 | 日本五十熟hd丰满 | 午夜精品一区二区三区三上悠亚 | 久久这里精品 | 在线观看免费中文字幕 | 日韩美女三级 | 超碰c| 狠狠操狠狠操 | 小箩莉末发育娇小性色xxxx | 午夜桃色 | 在线看片网址 | 天堂网av在线播放 | 精品久久影院 | 欧美老女人xx | 花样视频污 | 50一60岁老妇女毛片 | 亚洲精品v日韩精品 | 国产精品久久久久久久av福利 | 九七在线视频 | hitomi一区二区三区精品 | 亚洲福利社区 | 国产亚洲AV无码成人网站在线 | 免费在线观看黄色网址 |