多线程版爬取故事网

  • 前言:
    为了能以更高效的速度爬取,尝试采用了多线程
    本博客参照代码及PROJECT来源:http://kexue.fm/archives/4385/

  • 源代码:

     1 #! -*- coding:utf-8 -*-
     2 import requests as rq
     3 import re
     4 import time
     5 import datetime
     6 import pymysql
     7 from multiprocessing.dummy import Pool,Queue #dummy子库是多线程库
     8 import html
     9 from urllib.request import urlopen
    10 from bs4 import BeautifulSoup
    11 unescape = html.unescape #用来实现对HTML字符的转移
    12
    13 tasks = Queue() #链接队列
    14 tasks_pass = set() #已队列过的链接
    15 results = {} #结果变量
    16 count = 0 #爬取页面总数
    17 tasks.put(‘/index.html‘) #把主页加入到链接队列
    18 tasks_pass.add(‘/index.html‘) #把主页加入到已队列链接
    19
    20 def main(tasks):
    21     global results,count,tasks_pass #多线程可以很轻松地共享变量
    22     while True:
    23         url = tasks.get() #取出一个链接
    24         url = ‘http://wap.xigushi.com‘+url
    25         html = urlopen(url)
    26         bsObj = BeautifulSoup(html.read(), "lxml")
    27         if (bsObj.meta.attrs[‘charset‘]==‘gb2312‘):
    28             web = rq.get(url).content.decode(‘gbk‘)  # 这里的编码要看实际情形而定
    29         else:
    30             web = rq.get(url).content.decode(‘utf8‘)  # 这里的编码要看实际情形而定
    31
    32         urls = re.findall(‘href="(/.*?)"‘, web) #查找所有站内链接
    33         for u in urls:
    34             if (u not in tasks_pass): #把还没有队列过的链接加入队列
    35                 if ((re.search(‘images‘, url)) is None):
    36                     tasks.put(u)
    37                     tasks_pass.add(u)
    38                 else:
    39                     print(u, ‘---------------------------skipping--------------------------------------------‘)
    40             else:
    41                 pass
    42
    43         text = bsObj.title.get_text()
    44         print(datetime.datetime.now(), ‘   ‘, url, ‘   ‘, text)
    45         db = pymysql.connect("localhost", "testuser", "test123", "TESTDB", charset=‘gbk‘)
    46         dbc = db.cursor()
    47         sql = "insert ignore into data1(url,title) values(%s,%s);"
    48         data = (url, text)
    49         dbc.execute(sql, data)
    50         dbc.close()
    51         db.commit()
    52         db.close()
    53         count += 1
    54         if count % 100 == 0:
    55             print(u‘%s done.‘%count)
    56
    57 pool = Pool(10, main, (tasks,)) #多线程爬取,4是线程数
    58 total = 0
    59 while True: #这部分代码的意思是如果20秒内没有动静,那就结束脚本
    60     time.sleep(60)
    61     if len(tasks_pass) > total:
    62         total = len(tasks_pass)
    63     else:
    64         break
    65
    66 pool.terminate()
    67 print("terminated normally")

  • BUG:
  1. 数据库并发写入:
    解答来源:https://stackoverflow.com/questions/6650940/interfaceerror-0
    通过将游标的创建移入线程,并在线程内关闭,跑出来的结果比之前好一些,但奇怪的是多几行还是会出现并发报错,奇怪,还能错一半的?猜测将连接也放入线程会好些,或者干脆不用commit提交?结果是不用commit都没有写入数据库...我以为开启了自动提交呢...
    已解决,将数据库连接和游标都放在线程内创建
  2. 神奇地跳过一些数据库里面没有的链接:
    原来是过滤问题...水平真是...
    已解决,修改URL过滤方式
  3. 编码问题真是头都大了...
    encoding error : input conversion failed due to input error, bytes 0xB1 0x80 0xB5 0xC4

    为什么改了那么多次还有...显然是gbk转utf8问题,可是我判断了啊,还是有些网页就是比较乱...

  4. 又是编码问题:

    UnicodeEncodeError: ‘gbk‘ codec can‘t encode character ‘\u30fb‘ in position 86: illegal multibyte sequence
  5. 网络错误:

    urllib.error.HTTPError: HTTP Error 503: Forwarding failure
时间: 2024-10-13 11:29:31

多线程版爬取故事网的相关文章

使用python爬取东方财富网机构调研数据

最近有一个需求,需要爬取东方财富网的机构调研数据.数据所在的网页地址为: 机构调研 网页如下所示: 可见数据共有8464页,此处不能直接使用scrapy爬虫进行爬取,因为点击下一页时,浏览器只是发起了javascript网络访问,然后将服务器返回的数据插入网页,无法通过网址直接获取对应页的的页面数据. 通过chrome的开发者工具,我们可以看到点击下一页按钮背后发起的网页访问: 在点击下一页时,浏览器向地址发起了访问.我们分析一下这个地址的结构: http://data.eastmoney.co

Node.js爬虫-爬取慕课网课程信息

第一次学习Node.js爬虫,所以这时一个简单的爬虫,Node.js的好处就是可以并发的执行 这个爬虫主要就是获取慕课网的课程信息,并把获得的信息存储到一个文件中,其中要用到cheerio库,它可以让我们方便的操作HTML,就像是用jQ一样 开始前,记得 npm install cheerio 为了能够并发的进行爬取,用到了Promise对象 //接受一个url爬取整个网页,返回一个Promise对象 function getPageAsync(url){ return new Promise(

[PHP] 网盘搜索引擎-采集爬取百度网盘分享文件实现网盘搜索(二)

前情提要:最近使用PHP实现了简单的网盘搜索程序,并且关联了微信公众平台,名字是网盘小说.用户可以通过公众号输入关键字,公众号会返回相应的网盘下载地址.就是这么一个简单的功能,类似很多的网盘搜索类网站,我这个采集和搜索程序都是PHP实现的,全文和分词搜索部分使用到了开源软件xunsearch. 上一篇([PHP] 网盘搜索引擎-采集爬取百度网盘分享文件实现网盘搜索)中我重点介绍了怎样去获取一大批的百度网盘用户,这一篇介绍怎样获得指定网盘用户的分享列表.同样的原理,也是找到百度获取分享列表的接口,

Python爬取天气网历史天气数据

我的第一篇博客,哈哈哈,记录一下我的Python进阶之路! 今天写了一个简单的爬虫. 使用python的requests 和BeautifulSoup模块,Python 2.7.12可在命令行中直接使用pip进行模块安装.爬虫的核心是利用BeautifulSoup的select语句获取需要的信息. pip install requests pip install bs4 以武汉市2017年5~7月的历史为例爬取天气网中武汉市的历史天气数据. 7月对应的网址为http://lishi.tianqi

基于爬取百合网的数据,用matplotlib生成图表

爬取百合网的数据链接:http://www.cnblogs.com/YuWeiXiF/p/8439552.html 总共爬了22779条数据.第一次接触matplotlib库,以下代码参考了matplotlib官方文档:https://matplotlib.org/users/index.html. 数据查询用到了两个方法:getSexNumber(@sex varchar(2),@income varchar(30)).gethousingNumber(@sex varchar(2),@hou

爬取豆瓣网评论最多的书籍

相信很多人都有书荒的时候,想要找到一本合适的书籍确实不容易,所以这次利用刚学习到的知识爬取豆瓣网的各类书籍,传送门https://book.douban.com/tag/?view=cloud. 首先是这个程序的结构,html_downloader是html下载器,html_outputer是导出到Excel表,html_parser是解析页面,make_wordcloud是制作词云,spided_main是程序入口,url_manager是URL管理器 主要实现思路是先请求下载需要的html,

Scrapy爬虫(5)爬取当当网图书畅销榜

??本次将会使用Scrapy来爬取当当网的图书畅销榜,其网页截图如下: ??我们的爬虫将会把每本书的排名,书名,作者,出版社,价格以及评论数爬取出来,并保存为csv格式的文件.项目的具体创建就不再多讲,可以参考上一篇博客,我们只需要修改items.py文件,以及新建一个爬虫文件BookSpider.py. ??items.py文件的代码如下,用来储存每本书的排名,书名,作者,出版社,价格以及评论数. import scrapy class BookspiderItem(scrapy.Item):

Python爬虫项目--爬取自如网房源信息

本次爬取自如网房源信息所用到的知识点: 1. requests get请求 2. lxml解析html 3. Xpath 4. MongoDB存储 正文 1.分析目标站点 1. url: http://hz.ziroom.com/z/nl/z3.html?p=2 的p参数控制分页 2. get请求 2.获取单页源码 1 # -*- coding: utf-8 -*- 2 import requests 3 import time 4 from requests.exceptions import

python爬虫案例-爬取当当网数据

输入关键字,爬取当当网中商品的基本数据,代码如下: 1 # Author:K 2 import requests 3 from lxml import etree 4 from fake_useragent import UserAgent 5 import re 6 import csv 7 8 9 def get_page(key): 10 for page in range(1,50): 11 url = 'http://search.dangdang.com/?key=%s&act=in