图书2级域名https://book.jd.com/,进去随便点击一个左边的分类比如是小说
https://channel.jd.com/1713-3258.html.再点击一个分类地址变成
https://list.jd.com/list.html?cat=1713,3258,3304
目前的分类是小说->侦探/悬疑/推理
我们是遍历所有的书籍,不是去搜索,所以暂且不考虑搜索框.也不考虑下面更多分类.找到更高层分类,直接翻页就可以.
上面的图我们看出,其实图书下面的一级分类我们找到,然后后面的分类不用找.我们就可以遍历所有的图书了.问题分析好了.那么我们来整理一下步骤
1.找到一级分类所有url(类似https://list.jd.com/list.html?cat=1713,3258),其中1713与3258是可变的.随便找一个网页爬一下上图那个下拉div就可以找到所有.
2.爬翻页的规律
https://list.jd.com/list.html?cat=1713,3258&page=2&sort=sort_rank_asc&trans=1&JL=6_0_0#J_main
3.解析网页,找到对应的书名字.目前每页最大是60本书(这里不说套装的)
技术分析:
1.python语言
2.urllib做http请求
3.BeautifulSoup来对网页的数据进行筛选处理
4.threadpool可以使用多线程类爬取.
遇到问题:
1.当简单的使用翻页来请求遍历的时候,等到翻页有几张的时候,请求回来的数据不发生变化了.自己把地址放到浏览器访问的时候没有出现这样的情况.但是当我清空cookie的时候,也出现了并不是我想要的页数的数据.看来在访问的时候有一些数据是被吸入了cookie中.通过浏览器把cookie的数据也写到代码中来,ok.搞定.(cookie的东西实在太多 看不懂的都是数字)
Cookie: ipLoc-djd=1-72-4137-0; areaId=1; __jdv=122270672|direct|-|none|-|1486352895658; listck=737721c65cab60f4a47618c8270ce1d2; __jda=122270672.1486352895657625018347.1486352896.1486352896.1486352896.1; __jdb=122270672.5.1486352895657625018347|1.1486352896; __jdc=122270672; __jdu=1486352895657625018347
最后上一下代码:
#coding: utf-8
import sys
import urllib
import urllib2
import os
import threadpool
from bs4 import BeautifulSoup
from urllib2 import Request, urlopen, URLError
import chardet
import re
import time
import random
reload(sys)
sys.setdefaultencoding('utf8')
ids = []
for i in range(0,1):
#只放了一个,只爬小说的所有书籍
ids.append(3258+i)
URL = 'https://list.jd.com/list.html?cat=1713,'
def getPageCount(url):
htmlpage1 = urllib2.urlopen(url).read()
soup1 = BeautifulSoup(htmlpage1)
pagecount = soup1.find("div",{"class":"f-pager"}).span.i.get_text()
return int(pagecount)
def pa(url,pageNo,output):
#htmlpage = urllib2.urlopen(url+'&page='+str(pageNo)).read()
url = url+'&page='+str(pageNo)
req = urllib2.Request(url)
req.add_header('Accept-Language','zh-CN,zh;q=0.8')
req.add_header('Host','list.jd.com')
req.add_header('Upgrade-Insecure-Requests','1')
req.add_header('User-Agent','Mozilla/5.0 (Windows NT 10.0.10586; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2950.5 Safari/537.36')
req.add_header('Cookie','ipLoc-djd=1-72-4137-0; areaId=1; __jdv=122270672|direct|-|none|-|1486352895658; listck=c32c27080e5893ef3b481d0d8b0f3a3f; __jda=122270672.1486352895657625018347.1486352896.1486352896.1486356790.2; __jdb=122270672.7.1486352895657625018347|2.1486356790; __jdc=122270672; __jdu=1486352895657625018347')
htmlpage = urllib2.urlopen(req)
soup = BeautifulSoup(htmlpage)
#print len(soup.findAll("div", {"class": "f13"}))
#print soup
for result_table in soup.findAll("div", {"class": "gl-i-wrap j-sku-item"}):
pName = result_table.find("div", {"class": "p-name"}).a.em.get_text()
#pPrice = result_table.find("div", {"class": "p-price"}).strong
print pName
output.write(pName+'\r\n')
for result_table in soup.findAll("div", {"class": "tab-content-item tab-cnt-i-selected j-sku-item"}):
pName = result_table.find("div", {"class": "p-name"}).a.em.get_text()
#pPrice = result_table.find("div", {"class": "p-price"}).strong
print pName
output.write(pName+'\r\n')
def product(id):
output = open('data_prd.txt'+str(id), 'w+')
url = URL + str(id)
print url
pagecount = getPageCount(url)
start = 10
pages = []
while(start <= pagecount):
#pa(url,start)
pages.append(start)
start+=1
#random.shuffle(pages)
for p in pages:
print p
pa(url,p,output)
time.sleep(1)
pool = threadpool.ThreadPool(10) #建立线程池,控制线程数量为10
reqs = threadpool.makeRequests(product, ids) #构建请求,get_title为要运行的函数,data为要多线程执行函数的参数,最后这个print_result是可选的,是对前两个函数运行结果的操作
[pool.putRequest(req) for req in reqs] #多线程一块执行
pool.wait() #线程挂起,直到结束