python爬取十万级数据

前言

需要使用的模块beautifulsoup,然后结合mongodb来存放数据

使用beautifulsoup来爬取网页信息原理

我们可以通过审核元素来copy目标的路径信息,比较常用的有css selector和xpath(xpath被誉为神器,也比较容易理解,但是先学习beautifulsoup),但是beautifulsoup只认识css selector.所以我们通过复制目标的css selector来做到爬取它的目标

关于xpath和css selector

xpath : 谁,在哪,第几个
css selector : 谁,在哪,第几个,长什么样子

beautifulsoup使用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
* 导入所需要的库
from bs4 import BeautifulSoup
import requests
* 指定Url
url = ""
* 使用request来获取网页内容
data = requests.get(url)
* 使用beautifulsoup来解析网页
soup = BeautifulSoup(data.text,'lxml')
* 使用浏览器的审核元素,copy想要爬去元素的css selector
titles = soup.select('xxxxxx')
tags = soup.select('')
imgs = soup.select('img[width="30"]')
****
注意:
---文章的标签通常是多对一结构,要获得一个信息的所有标签,就要在标签的父级目录停下来
---可以在select中添加目标的特殊信息,例如soup.select('img[width="30"]')筛选出img标签中宽为10的图片。
****
* 筛选信息,将他们装在一个字典中
for title,tag,img in zip(titles,tags,imgs):
data = {
'title':title.get_text(), #get_text方法是获取标签的正文
'tag':list(tag.stripped_strings) 如果用get_text只会获取其中的一个,stripped_strings算是get_text的升级版本,获取一个父级标签下所有子标签的正文
'img':img.get('src') get是获取标签的属性值,对于图片,我们通常爬取的是他的链接
}
print(data)

如果要对他进行优化,比如我想筛选出评分大于3的文章

1
2
3
4
5
6
info = []
info.append(data)
for i in info:
if i['cate']>3:
print(i['title'])
....


小技巧,比如爬取图片地址,有些地址是在js文件中,所以爬取很麻烦,我们可以通过chrome浏览器中的模拟手机功能来利用相同的方法来抓取,因为手机端不会加载过多的js文件,这样一来爬取图片链接也简单了许多。

注意:使用request记得在里边添加headers,让服务器知道你是手机端而不是电脑。

mongodb使用方法

对于下载和使用mongodb可以参考MongoDB 教程
还有pycharm中mongo插件的使用,以及下载安装与mongodb做连接的pymongo库…

对于代码中mongodb的创建,我们可以把他和execl来联系起来。我们先要给一个表名称,而这个表的主体内容还可以分为sheet1,sheet2….

1
2
3
4
5
6
7
8
9
10
11
12
13
14
* 导入可以与mongodb连接的库文件,当然前提你要安装Mongodb
import pymongo
* 激活mongodb,因为我们是部署在本地中,所以创建在本地
client = pymongo.MongoClient('localhost',27017)
* 给execl一个标题
execl0 = client('execl0') 左边的是Python对象,右边的是mongodb中数据库名称,建议一致
* 给execl一个sheet
sheet1 = execl0['sheet1'] 在execl0中创建一个sheet
* 此处从beautifulsoup那里连接开始
sheet1.insert_one(data) 这个是在表execl0中的sheet1中插入数据
* 使用find来找出数据,find后边可以添加条件,条件要为字典格式。使用以下指令来进行筛选,$lt/$lte/$gt/$gte/$ne依次等价于 <、<=、>、>=、!=。
*格式 sheet1.find({'评分':$lt3})
for item in sheet1.find():
print item

实战-开始爬取58同城数据

first.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

from bs4 import BeautifulSoup
import requests


# client = pymongo.MongoClient('localhost',27017)
# walden = client['walden']
# sheet = walden['sheet']

url = 'http://jq.58.com/sale.shtml'
url_host = 'http://jq.58.com/'
def get_info(url):
web_data = requests.get(url)
soup = BeautifulSoup(web_data.text,'lxml')
links = soup.select('ul.ym-submnu > li > b > a')
for i in links:
page = url_host + i.get('href')
print(page)
chew_link = '''
http://jq.58.com//shouji/
http://jq.58.com//shoujihao/
http://jq.58.com//tongxunyw/
http://jq.58.com//danche/
http://jq.58.com//fzixingche/
http://jq.58.com//diandongche/
http://jq.58.com//sanlunche/
http://jq.58.com//peijianzhuangbei/
http://jq.58.com//diannao/
http://jq.58.com//bijiben/
http://jq.58.com//pbdn/
http://jq.58.com//diannaopeijian/
http://jq.58.com//zhoubianshebei/
http://jq.58.com//shuma/
http://jq.58.com//shumaxiangji/
http://jq.58.com//mpsanmpsi/
http://jq.58.com//youxiji/
http://jq.58.com//jiadian/
http://jq.58.com//dianshiji/
http://jq.58.com//ershoukongtiao/
http://jq.58.com//xiyiji/
http://jq.58.com//bingxiang/
http://jq.58.com//binggui/
http://jq.58.com//chuang/
http://jq.58.com//ershoujiaju/
http://jq.58.com//bangongshebei/
http://jq.58.com//diannaohaocai/
http://jq.58.com//bangongjiaju/
http://jq.58.com//ershoushebei/
http://jq.58.com//yingyou/
http://jq.58.com//yingeryongpin/
http://jq.58.com//muyingweiyang/
http://jq.58.com//muyingtongchuang/
http://jq.58.com//yunfuyongpin/
http://jq.58.com//fushi/
http://jq.58.com//nanzhuang/
http://jq.58.com//fsxiemao/
http://jq.58.com//xiangbao/
http://jq.58.com//meirong/
http://jq.58.com//yishu/
http://jq.58.com//shufahuihua/
http://jq.58.com//zhubaoshipin/
http://jq.58.com//yuqi/
http://jq.58.com//tushu/
http://jq.58.com//tushubook/
http://jq.58.com//wenti/
http://jq.58.com//yundongfushi/
http://jq.58.com//jianshenqixie/
http://jq.58.com//huju/
http://jq.58.com//qiulei/
http://jq.58.com//yueqi/
http://jq.58.com//chengren/
http://jq.58.com//nvyongpin/
http://jq.58.com//qinglvqingqu/
http://jq.58.com//qingquneiyi/
http://jq.58.com//chengren/
http://jq.58.com//xiaoyuan/
http://jq.58.com//ershouqiugou/
http://jq.58.com//tiaozao/
http://jq.58.com//tiaozao/
http://jq.58.com//tiaozao/

'''

second.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from bs4 import BeautifulSoup
import pymongo
import requests

client = pymongo.MongoClient('localhost',27017)
walden = client['walden']
sheet = walden['sheet']
info = walden['info']

def get_link(url,page,who_sell=0):
#http://jq.58.com/shouji/
chew_list = '{}{}/pn{}'.format(url,str(who_sell),str(page))
web_data = requests.get(chew_list)
soup = BeautifulSoup(web_data.text,'lxml')
src = soup.select(' div.infocon > table > tbody > tr.zzinfo > td.t > a')
for links in src:
a = links.get('href').split('?')[0]
sheet.insert_one({'link':a})
print(a)

def get_info(url):
web_data = requests.get(url)
soup = BeautifulSoup(web_data.text,'lxml')
title = soup.title.text
price = soup.select('div.info_lubotu.clearfix > div.info_massege.left > div.price_li > span')[0].text
area = soup.select('div.info_lubotu.clearfix > div.info_massege.left > div.palce_li > span')[0].text
info.insert_one({
'title':title,
'price':price,
'area':area
})

third.py

1
2
3
4
5
6
7
8
9
10
11
from multiprocessing import Pool
from first import chew_link
from second import get_link

def total_link(url):
for num in range(1,101):
get_link(url,num)

if __name__ == '__main__':
pool = Pool()
pool.map(total_link,chew_link.split())

fourth,py

1
2
3
4
5
import time
from second import sheet
while True:
print(sheet.find().count())
time.sleep(3)

以上就是python+mongodb+beautifulsoup+多进程 来爬取十万级数据的方法,但是比较懒,还有好多优化的地方以变得更加方便以及更少的代码,但是没有进行优化…这是一大不足

fourth.py实现了一个数据库计数的功能。third.py结合first.py,second.py的方法,在结合多进程来来实现。

second.py是爬取通过first传递过来的所需要的信息。运行时运行fourth和third就可以了。

QQ:709516041 如有不懂的可以来问我,也欢迎有大神前来指点我的不足

同时也在此感谢俊富给我的资料。