Rumah pembangunan bahagian belakang Tutorial Python python爬取网站数据保存使用的方法

python爬取网站数据保存使用的方法

Jun 16, 2016 am 08:46 AM
python

编码问题
因为涉及到中文,所以必然地涉及到了编码的问题,这一次借这个机会算是彻底搞清楚了。
问题要从文字的编码讲起。原本的英文编码只有0~255,刚好是8位1个字节。为了表示各种不同的语言,自然要进行扩充。中文的话有GB系列。可能还听说过Unicode和UTF-8,那么,它们之间是什么关系呢?
Unicode是一种编码方案,又称万国码,可见其包含之广。但是具体存储到计算机上,并不用这种编码,可以说它起着一个中间人的作用。你可以再把Unicode编码(encode)为UTF-8,或者GB,再存储到计算机上。UTF-8或者GB也可以进行解码(decode)还原为Unicode。
在python中Unicode是一类对象,表现为以u打头的,比如u'中文',而string又是一类对象,是在具体编码方式下的实际存在计算机上的字符串。比如utf-8编码下的'中文'和gbk编码下的'中文',并不相同。可以看如下代码:

复制代码 代码如下:

>>> str=u'中文'
>>> str1=str.encode('utf8')
>>> str2=str.encode('gbk')
>>> print repr(str)
u'\u4e2d\u6587'
>>> print repr(str1)
'\xe4\xb8\xad\xe6\x96\x87'
>>> print repr(str2)
'\xd6\xd0\xce\xc4'

可以看到,其实存储在计算机中的只是这样的编码,而不是一个一个的汉字,在print的时候要知道当时是用的什么样的编码方式,才能正确的print出来。有一个说法提得很好,python中的Unicode才是真正的字符串,而string是字节串
文件编码
既然有不同的编码,那么如果在代码文件中直接写string的话,那么它到底是哪一种编码呢?这个就是由文件的编码所决定的。文件总是以一定的编码方式保存的。而python文件可以写上coding的声明语句,用来说明这个文件是用什么编码方式保存的。如果声明的编码方式和实际保存的编码方式不一致就会出现异常。可以见下面例子: 以utf-8保存的文件声明为gbk

复制代码 代码如下:

#coding:gbk
str=u'汉'
str1=str.encode('utf8')
str2=str.encode('gbk')
str3='汉'
print repr(str)
print repr(str1)
print repr(str2)
print repr(str3)

提示错误 File "test.py", line 1 SyntaxError: Non-ASCII character '\xe6' in file test.py on line 1, but no encodi ng declared; see http://www.python.org/peps/pep-0263.html for details 改为

复制代码 代码如下:

#coding:utf8
str=u'汉'
str1=str.encode('utf8')
str2=str.encode('gbk')
str3='汉'
print repr(str)
print repr(str1)
print repr(str2)
print repr(str3)

输出正常结果 u'\u6c49' '\xe6\xb1\x89' '\xba\xba' '\xe6\xb1\x89'

基本方法
其实用python爬取网页很简单,只有简单的几句话

复制代码 代码如下:

import urllib2
page=urllib2.urlopen('url').read()

这样就可以获得到页面的内容。接下来再用正则匹配去匹配所需要的内容就行了。
但是,真正要做起来,就会有各种各样的细节问题。
登录
这是一个需要登录认证的网站。也不太难,只要导入cookielib和urllib库就行。

复制代码 代码如下:

import urllib,urllib2,cookielib
cookiejar = cookielib.CookieJar()
urlOpener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))

这样就装载进一个cookie,用urlOpener去open登录以后就可以记住信息。
断线重连
如果只是做到上面的程度,不对open进行包装的话,只要网络状况有些起伏,就直接抛出异常,退出整个程序,是个很不好的程序。这个时候,只要对异常进行处理,多试几次就行了:

复制代码 代码如下:

def multi_open(opener,*arg):
    while True:
        retryTimes=20
        while retryTimes>0:
            try:
                return opener.open(*arg)
            except:
                print '.',
                retryTimes-=1

正则匹配
其实正则匹配并不算是一个特别好的方法,因为它的容错性很不好,网页要完全统一。如果有稍微的不统一,就会失败。后来看到说有根据xpath来进行选取的,下次可以尝试一下。
写正则其实是有一定技巧的:
非贪婪匹配。比如这样一个标签:hello,要取出a来,如果写成这样的表达式,就不行了:hello。因为*进行了贪婪匹配。这是要用.?:hello
跨行匹配。实现跨行有一种思路是运用DOTALL标志位,这样.就会匹配到换行。但是这样一来,整个匹配过程就会变得很慢。本来的匹配是以行为单位的。整个过程最多就是O(nc2),n是行数,c是平均列数。现在极有可能变为O((nc)2)。我的实现方案是运用\n来匹配换行,这样可以明确指出匹配最多跨跃多少行。比如:abc\s*\n\s*def,就指出查找的是隔一行的。(.\n)?就可以指定是匹配尽可能少的行。
这里其实还要注意一个点。有的行末是带有\r的。也就是说一行是以\r\n结尾的。当初不知道这一点,正则就调试了很久。现在直接用\s,表示行末空格和\r。
无捕获分组。为了不对捕获的分组造成影响,上面的(.\n)可以改为(?:.\n),这样捕获分组时,就会忽略它。
单括号要进行转义。因为单括号在正则里是用来表示分组的,所以为了匹配单括号就进行转义。正则字符串最好用的是带有r前缀的字符串,如果不是的话,则要对\再进行转义。
快速正则。写了那么多模式,也总结出一规律出来。先把要匹配的字符相关的段落拿出来。要匹配的东西用(.?)代替。把换行\n替换为字符串\s\n\s*,再去掉行首行末的空格。整个过程在vim中可以很快就写好。
Excel操作
这次的数据是放进Excel的。到后面才意识到如果放进数据库的话,可能就没有那么多事了。但是已经写到一半,难以回头了。
搜索Excel,可以得出几个方案来,一个是用xlrt/xlwt库,这个不管电脑上是否安装了Excel,都可以运行,但只能是xls格式的。还有一个是直接包装了com,需要电脑上安装了软件才行。我采用的是前一种。
基本的读写没有问题。但是数据量一大起来,就有问题了。
内存不够。程序一跑起来,内存占用就一点一点往上涨。后面再查了一下,知道要用flush_row_data。但是还是会出错。一看内存占用,没有什么问题,一直很平稳。但最后还是会出现memory error。这真是见鬼了。又是反复地查, 反复地运行。一点结果都没有。要命的是bug只在数据量大起来才出现,而等数据量大起来往往要好几个小时,这debug的成本实在是太高了。一个偶然的机会,突然发现内存占用,虽然总体平稳,但是会规律性的出现小的高涨,而这规律性,会不会和flush_row_data,有关。一直疑惑的是data被flush到了哪里。原来xlwt的作法是很蛋疼的作法。把数据存在内存里,或者flush到一个temp,到save的时候,再一次性写入。而问题正出在这一次性写入,内存猛涨。那我要flush_row_data何用?为什么不一开始就flush进要写入的地方。
行数限制。这个是xls格式本身决定的,最多行数只能是65536。而且数据一大,文件打开也不方便。
结合以上两点,最终采取了这么一个策略,如果行数是1000的倍数,进行一次flush,如果行数超过65536,新开一个sheet,如果超过3个sheet,则新建一个文件。为了方便,把xlwt包装了一下

复制代码 代码如下:

#coding:utf-8#
import xlwt

class XLS:
    '''a class wrap the xlwt'''
    MAX_ROW=65536
    MAX_SHEET_NUM=3

    def __init__(self,name,captionList,typeList,encoding='utf8',flushBound=1000):
        self.name=name
        self.captionList=captionList[:]
        self.typeList=typeList[:]
        self.workbookIndex=1
        self.encoding=encoding
        self.wb=xlwt.Workbook(encoding=self.encoding)
        self.sheetIndex=1
        self.__addSheet()
        self.flushBound=flushBound

    def __addSheet(self):
        if self.sheetIndex != 1:
            self.wb.save(self.name+str(self.workbookIndex)+'.xls')
        if self.sheetIndex>XLS.MAX_SHEET_NUM:
            self.workbookIndex+=1
            self.wb=xlwt.Workbook(encoding=self.encoding)
            self.sheetIndex=1

        self.sheet=self.wb.add_sheet(self.name.encode(self.encoding)+str(self.sheetIndex))
        for i in range(len(self.captionList)):
            self.sheet.write(0,i,self.captionList[i])

        self.row=1

    def write(self,data):
        if self.row>=XLS.MAX_ROW:
            self.sheetIndex += 1
            self.__addSheet()

        for i in range(len(data)):
            if self.typeList[i]=="num":
                try:
                    self.sheet.write(self.row,i,float(data[i]))
                except ValueError:
                    pass
            else:
                self.sheet.write(self.row,i,data[i])

        if self.row % self.flushBound == 0:
            self.sheet.flush_row_data()
        self.row+=1

    def save(self):
        self.wb.save(self.name+str(self.workbookIndex)+'.xls')

转换网页特殊字符
由于网页也有自己独特的转义字符,在进行正则匹配的时候就有些麻烦。在官方文档中查到一个用字典替换的方案,私以为不错,拿来做了一些扩充。其中有一些是为保持正则的正确性。

复制代码 代码如下:

html_escape_table = {
    "&": "&",
    '"': """,
    "'": "'",
    ">": ">",
    "    u"·":"·",
    u"°":"°",
    #regular expression
    ".":r"\.",
    "^":r"\^",
    "$":r"\$",
    "{":r"\{",
    "}":r"\}",
    "\\":r"\\",
    "|":r"\|",
    "(":r"\(",
    ")":r"\)",
    "+":r"\+",
    "*":r"\*",
    "?":r"\?",
}

def html_escape(text):
    """Produce entities within text."""
    tmp="".join(html_escape_table.get(c,c) for c in text)
    return tmp.encode("utf-8")


得出的经验差不多就是这些了。不过最后写出来的程序自已也不忍再看。风格很不好。一开始想着先写着试试。然后试着试着就不想改了。
最终的程序要跑很久,其中网络通信时间占了大部分。是不是可以考虑用多线程重构一下?想想,还是就这样吧。

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Adakah Mysql perlu membayar Adakah Mysql perlu membayar Apr 08, 2025 pm 05:36 PM

MySQL mempunyai versi komuniti percuma dan versi perusahaan berbayar. Versi komuniti boleh digunakan dan diubahsuai secara percuma, tetapi sokongannya terhad dan sesuai untuk aplikasi dengan keperluan kestabilan yang rendah dan keupayaan teknikal yang kuat. Edisi Enterprise menyediakan sokongan komersil yang komprehensif untuk aplikasi yang memerlukan pangkalan data yang stabil, boleh dipercayai, berprestasi tinggi dan bersedia membayar sokongan. Faktor yang dipertimbangkan apabila memilih versi termasuk kritikal aplikasi, belanjawan, dan kemahiran teknikal. Tidak ada pilihan yang sempurna, hanya pilihan yang paling sesuai, dan anda perlu memilih dengan teliti mengikut keadaan tertentu.

Cara Menggunakan MySQL Selepas Pemasangan Cara Menggunakan MySQL Selepas Pemasangan Apr 08, 2025 am 11:48 AM

Artikel ini memperkenalkan operasi pangkalan data MySQL. Pertama, anda perlu memasang klien MySQL, seperti MySqlworkbench atau Command Line Client. 1. Gunakan perintah MySQL-Uroot-P untuk menyambung ke pelayan dan log masuk dengan kata laluan akaun root; 2. Gunakan CreateTatabase untuk membuat pangkalan data, dan gunakan Pilih pangkalan data; 3. Gunakan createtable untuk membuat jadual, menentukan medan dan jenis data; 4. Gunakan InsertInto untuk memasukkan data, data pertanyaan, kemas kini data dengan kemas kini, dan padam data dengan padam. Hanya dengan menguasai langkah -langkah ini, belajar menangani masalah biasa dan mengoptimumkan prestasi pangkalan data anda boleh menggunakan MySQL dengan cekap.

Mysql tidak dapat dipasang setelah memuat turun Mysql tidak dapat dipasang setelah memuat turun Apr 08, 2025 am 11:24 AM

Sebab utama kegagalan pemasangan MySQL adalah: 1. Isu kebenaran, anda perlu menjalankan sebagai pentadbir atau menggunakan perintah sudo; 2. Ketergantungan hilang, dan anda perlu memasang pakej pembangunan yang relevan; 3. Konflik pelabuhan, anda perlu menutup program yang menduduki port 3306 atau mengubah suai fail konfigurasi; 4. Pakej pemasangan adalah korup, anda perlu memuat turun dan mengesahkan integriti; 5. Pembolehubah persekitaran dikonfigurasikan dengan salah, dan pembolehubah persekitaran mesti dikonfigurasi dengan betul mengikut sistem operasi. Selesaikan masalah ini dan periksa dengan teliti setiap langkah untuk berjaya memasang MySQL.

Fail muat turun MySQL rosak dan tidak boleh dipasang. Penyelesaian pembaikan Fail muat turun MySQL rosak dan tidak boleh dipasang. Penyelesaian pembaikan Apr 08, 2025 am 11:21 AM

Fail muat turun mysql adalah korup, apa yang perlu saya lakukan? Malangnya, jika anda memuat turun MySQL, anda boleh menghadapi rasuah fail. Ia benar -benar tidak mudah hari ini! Artikel ini akan bercakap tentang cara menyelesaikan masalah ini supaya semua orang dapat mengelakkan lencongan. Selepas membacanya, anda bukan sahaja boleh membaiki pakej pemasangan MySQL yang rosak, tetapi juga mempunyai pemahaman yang lebih mendalam tentang proses muat turun dan pemasangan untuk mengelakkan terjebak pada masa akan datang. Mari kita bercakap tentang mengapa memuat turun fail rosak. Terdapat banyak sebab untuk ini. Masalah rangkaian adalah pelakunya. Gangguan dalam proses muat turun dan ketidakstabilan dalam rangkaian boleh menyebabkan rasuah fail. Terdapat juga masalah dengan sumber muat turun itu sendiri. Fail pelayan itu sendiri rosak, dan sudah tentu ia juga dipecahkan jika anda memuat turunnya. Di samping itu, pengimbasan "ghairah" yang berlebihan beberapa perisian antivirus juga boleh menyebabkan rasuah fail. Masalah Diagnostik: Tentukan sama ada fail itu benar -benar korup

Bagaimana untuk mengoptimumkan prestasi MySQL untuk aplikasi beban tinggi? Bagaimana untuk mengoptimumkan prestasi MySQL untuk aplikasi beban tinggi? Apr 08, 2025 pm 06:03 PM

Panduan Pengoptimuman Prestasi Pangkalan Data MySQL Dalam aplikasi yang berintensifkan sumber, pangkalan data MySQL memainkan peranan penting dan bertanggungjawab untuk menguruskan urus niaga besar-besaran. Walau bagaimanapun, apabila skala aplikasi berkembang, kemunculan prestasi pangkalan data sering menjadi kekangan. Artikel ini akan meneroka satu siri strategi pengoptimuman prestasi MySQL yang berkesan untuk memastikan aplikasi anda tetap cekap dan responsif di bawah beban tinggi. Kami akan menggabungkan kes-kes sebenar untuk menerangkan teknologi utama yang mendalam seperti pengindeksan, pengoptimuman pertanyaan, reka bentuk pangkalan data dan caching. 1. Reka bentuk seni bina pangkalan data dan seni bina pangkalan data yang dioptimumkan adalah asas pengoptimuman prestasi MySQL. Berikut adalah beberapa prinsip teras: Memilih jenis data yang betul dan memilih jenis data terkecil yang memenuhi keperluan bukan sahaja dapat menjimatkan ruang penyimpanan, tetapi juga meningkatkan kelajuan pemprosesan data.

Cara mengoptimumkan prestasi pangkalan data selepas pemasangan MySQL Cara mengoptimumkan prestasi pangkalan data selepas pemasangan MySQL Apr 08, 2025 am 11:36 AM

Pengoptimuman prestasi MySQL perlu bermula dari tiga aspek: konfigurasi pemasangan, pengindeksan dan pengoptimuman pertanyaan, pemantauan dan penalaan. 1. Selepas pemasangan, anda perlu menyesuaikan fail my.cnf mengikut konfigurasi pelayan, seperti parameter innodb_buffer_pool_size, dan tutup query_cache_size; 2. Buat indeks yang sesuai untuk mengelakkan indeks yang berlebihan, dan mengoptimumkan pernyataan pertanyaan, seperti menggunakan perintah menjelaskan untuk menganalisis pelan pelaksanaan; 3. Gunakan alat pemantauan MySQL sendiri (ShowProcessList, ShowStatus) untuk memantau kesihatan pangkalan data, dan kerap membuat semula dan mengatur pangkalan data. Hanya dengan terus mengoptimumkan langkah -langkah ini, prestasi pangkalan data MySQL diperbaiki.

Penyelesaian kepada perkhidmatan yang tidak dapat dimulakan selepas pemasangan MySQL Penyelesaian kepada perkhidmatan yang tidak dapat dimulakan selepas pemasangan MySQL Apr 08, 2025 am 11:18 AM

MySQL enggan memulakan? Jangan panik, mari kita periksa! Ramai kawan mendapati bahawa perkhidmatan itu tidak dapat dimulakan selepas memasang MySQL, dan mereka sangat cemas! Jangan risau, artikel ini akan membawa anda untuk menangani dengan tenang dan mengetahui dalang di belakangnya! Selepas membacanya, anda bukan sahaja dapat menyelesaikan masalah ini, tetapi juga meningkatkan pemahaman anda tentang perkhidmatan MySQL dan idea anda untuk masalah penyelesaian masalah, dan menjadi pentadbir pangkalan data yang lebih kuat! Perkhidmatan MySQL gagal bermula, dan terdapat banyak sebab, mulai dari kesilapan konfigurasi mudah kepada masalah sistem yang kompleks. Mari kita mulakan dengan aspek yang paling biasa. Pengetahuan asas: Penerangan ringkas mengenai proses permulaan perkhidmatan MySQL Startup. Ringkasnya, sistem operasi memuatkan fail yang berkaitan dengan MySQL dan kemudian memulakan daemon MySQL. Ini melibatkan konfigurasi

Adakah mysql memerlukan internet Adakah mysql memerlukan internet Apr 08, 2025 pm 02:18 PM

MySQL boleh berjalan tanpa sambungan rangkaian untuk penyimpanan dan pengurusan data asas. Walau bagaimanapun, sambungan rangkaian diperlukan untuk interaksi dengan sistem lain, akses jauh, atau menggunakan ciri -ciri canggih seperti replikasi dan clustering. Di samping itu, langkah -langkah keselamatan (seperti firewall), pengoptimuman prestasi (pilih sambungan rangkaian yang betul), dan sandaran data adalah penting untuk menyambung ke Internet.

See all articles