Scrapy - Công cụ bóc tách dữ liệu siêu mạnh
Bài viết hôm nay mình giới thiệu với các bạn về package scrapy, một công cụ tạo web spider cực mạnh. Rất nhiều dự án và ứng dụng mình sử dụng scrapy, ví dụ như lấy toàn bộ hình ảnh của một website, các bài viết theo danh mục và theo chủ đề, tạo bot lấy dữ liệu nguời dùng như số điện thoại và email trên facebook.. hoặc đơn giản hơn là lấy kết quả sổ xố kiến thiết ...
Nghe cũng hấp dẫn ấy chứ, chỉ vài dòng code bạn sẽ có ngay một thằng làm thuê siêng năng không biết than thở là gì :d. Để chuẩn bị cho scrapy chúng ta cần cài đặt những package sau
Cài đặt
pip install scrapy
Bắt đầu project
Trong bài viết này mình sẽ sử dụng scrapy để lấy dữ liệu kết quả sổ xố từ website http://xskt.com.vn, bạn nào muốn tạo trang web mở đại lý có thể sử dụng source này :d. Trên virtual environment command line. Bạn hãy chạy dòng sau
scrapy startproject xskt
Scrapy sẽ tạo một folder và các file như sau
- scrapy.cfg: file config project scrapy
- settings.py: file chứa settings cho spiders
- middlewares.py: file chứa spider middlewares, là những framework được hook vào scrapy processing.
- items.py: file chứa cấu trúc của item mà bạn sẽ tách dữ liệu. Nói đơn giản thì nó là một cái khung, sau khi chúng ta lấy được dữ liệu từ spiders, chúng ta sẽ đặt dữ liệu vào đây và xử lý
- pipelines.py: sau khi chúng ta đặt dữ liệu vào cho items.py, chúng ta sẽ xử lý ở function process_items trong pipeline. Bạn có thể save vào database, hoặc chỉ trả về item đó
- folder spiders: là nơi chúng ta tạo file spider để chạy dữ liệu.
Phần giới thiệu các file cơ bản của scrapy đã xong. Bây giờ quay lại project của chúng ta, bạn cần nhớ rằng khi muốn lấy dữ liệu của một site nào đó, thì điều quan trọng là phân tích cấu trúc website. những dữ liệu nào trên site đó ta cần lấy, có những link nào trên site đó hỗ trợ ta lấy dữ liệu dễ dàng... Bây giờ tổng hợp lại những điều mình đã nêu ra, ta sẽ phân tích site http://xskt.com.vn
Kết quả xổ số được chia làm 3 miền, mình sẽ lấy miền nam làm ví dụ, các bạn làm tương tự cho các miền còn lại nha. Khi bạn vào site, kéo xuống chút sẽ thấy "Kết quả sổ xố toàn quốc". Tại đây chúng ta sẽ click vào miền nam
browser sẽ đưa chúng ta xuống phần "KQXS Miền Nam". Ở mục này sẽ có 3 link dẫn đến mục kết quả sổ xố: "KQXS Miền Nam" sẽ đưa bạn đến trang chứa kết quả mới nhất toàn miền nam, "Ngày 01/6" đưa đến trang chứa kết quả theo ngày, "Thứ Năm" sẽ đưa đến kết quả sổ xố ngày thứ năm. Để dễ dàng lấy dữ liệu từ tất cả các ngày trong ngày, tháng năm ta sẽ chọn link từ "Ngày 01/6" và lấy tiếp link từ "Ngày 01-6-2018"
Link sẽ có dạng là http://xskt.com.vn/ket-qua-xo-so-theo-ngay/mien-nam-xsmn/01-6-2018.html . Bạn hãy thay đổi ngày tháng của link này xem thử kết quả có như yêu cầu của project ta đang cần không.
Coding
Bây giờ quay lại phần coding nha, bạn hãy mở file items.py lên và chỉnh sửa như sau:
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class XsktItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
xs_info = scrapy.Field()
xs_data = scrapy.Field()
Ta tạo 2 item cho xskt là xs_info và xs_data. xs_info dùng lưu trữ thứ ngày tháng của bảng xổ số, xs_data dùng lưu trữ kết quả xổ số các tỉnh miền nam
Mở file settings.py lên và bạn hãy thêm FEED_FORMAT ở cuối file
FEED_FORMAT = 'json'
FEED_FORMAT cho phép bạn định dạng dữ liệu xuất ra theo dạng nào, mình sẽ xuất ra ở dạng json trong ví dụ này
Tiếp theo bạn hãy tạo file xosokienthiet.py trong folder xskt/xskt/spiders
import scrapy
import calendar
import datetime
from scrapy.spiders import CrawlSpider
from ..items import XsktItem #1
def get_total_date_month(year, month): #2
now = datetime.datetime.now()
total_date = calendar.monthrange(year, month)[1]
if year == now.year and month == now.month and now.day < total_date:
return now.day
return total_date
- Ta import XsktItem vào spider để chuẩn bị đổ dữ liệu lấy được vào item
- Function get_total_date_month sẽ tính toán xem có bao nhiêu ngày trong tháng mà chúng ta đưa vào. Nếu cùng năm và cùng tháng thì ta chỉ lấy tới ngày hiện tại
Tiếp tục ta sẽ tạo class SoxokienthietSpider để lấy dữ liệu từ site xskt.com.vn
class SoxokienthietSpider(CrawlSpider):
name = 'xosokienthiet'
allowed_domains = ['xskt.com.vn'] #1
start_urls = []
month_to_scrap = 5
year_to_scrap = 2018
total_date = get_total_date_month(year_to_scrap, month_to_scrap)
for i in range(1, total_date):
start_urls.append('http://xskt.com.vn/ket-qua-xo-so-theo-ngay/mien-nam-xsmn/'
'{0}-{1}-{2}.html'.format(i, month_to_scrap, year_to_scrap)) #2
def parse(self, response): #3
xs_item = XsktItem()
tmp_data = {}
data_resp = scrapy.Selector(response)
xs_item['xs_info'] = [
# Thứ
data_resp.xpath("//table[@id='MN0']/tr/th[1]/a/text()").extract_first(),
# Ngày tháng
data_resp.xpath("//table[@id='MN0']/tr/th[1]/text()").extract_first()
] #4
for i in range(2, 5):
# Các tỉnh trong bảng xổ số
tmp_location = data_resp.xpath("//table[@id='MN0']/tr/th[{0}]/a/text()".format(i)).extract_first()
tmp_data[tmp_location] = {}
for j in range(2, 11):
# Cột các giải từ giải 8 đến giải đặc biệt
tmp_giai = data_resp.xpath("//table[@id='MN0']/tr[{0}]/td[1]/text()".format(j)).extract_first()
# Các số trúng thưởng trong cột theo tỉnh
tmp_number = data_resp.xpath("//table[@id='MN0']/tr[{0}]/td[{1}]//text()".format(j, i)).extract()
tmp_data[tmp_location][tmp_giai] = ", ".join(tmp_number)
xs_item['xs_data'] = tmp_data #5
yield xs_item #6
- Scrapy cho phép chúng ta quản lý link theo domain để lấy dữ liệu, những domain ngoài allowed_domain scrapy sẽ bỏ qua
- Ta lấy số ngày từ function get_total_date_month sau đó đưa vào vòng lặp for. Bạn còn nhớ link (http://xskt.com.vn/ket-qua-xo-so-theo-ngay/mien-nam-xsmn/01-6-2018.html) mà ta phân tích lúc trước chứ. Chúng ta sẽ đưa các giá trị như ngày, tháng, năm vào để tạo một list cho scrapy chạy lấy dữ liệu.
- parse là function kế thừa từ class CrawlSpider. Function này sẽ parse respone lấy được của từng link trong danh sách trên
- Ta đưa thứ ngày tháng được phân tích từ xpath vào xs_info. extract_first() sẽ trả về trực tiếp giá trị là string. Mình sẽ trình bày tại sao có được xpath này ở phần dưới
- Tương tự cho xs_data, ta đưa số các giải vào.
- Yield tương tự như return, nhưng điểm khác biệt là nó sẽ lưu lại dữ liệu được yield, sau đó khi kết thúc nó sẽ trả về toàn bộ dữ liệu mà chương trình đã chạy. Bạn cần lưu ý là yield không lưu ở memory, mà được tạo ra và dùng trực tiếp. Tham khảo thêm tại đây
Code file xosokienthiet.py sẽ như sau
import scrapy
import calendar
import datetime
from scrapy.spiders import CrawlSpider
from ..items import XsktItem
def get_total_date_month(year, month):
now = datetime.datetime.now()
total_date = calendar.monthrange(year, month)[1]
if year == now.year and month == now.month and now.day < total_date:
return now.day
return total_date
class SoxokienthietSpider(CrawlSpider):
name = 'xosokienthiet'
allowed_domains = ['xskt.com.vn']
start_urls = []
month_to_scrap = 5
year_to_scrap = 2018
total_date = get_total_date_month(year_to_scrap, month_to_scrap)
for i in range(1, total_date):
start_urls.append('http://xskt.com.vn/ket-qua-xo-so-theo-ngay/mien-nam-xsmn/'
'{0}-{1}-{2}.html'.format(i, month_to_scrap, year_to_scrap))
def parse(self, response):
xs_item = XsktItem()
tmp_data = {}
data_resp = scrapy.Selector(response)
xs_item['xs_info'] = [
# Thứ
data_resp.xpath("//table[@id='MN0']/tr/th[1]/a/text()").extract_first(),
# Ngày tháng
data_resp.xpath("//table[@id='MN0']/tr/th[1]/text()").extract_first(),
self.year_to_scrap
]
for i in range(2, 5):
# Các tỉnh trong bảng xổ số
tmp_location = data_resp.xpath("//table[@id='MN0']/tr/th[{0}]/a/text()".format(i)).extract_first()
tmp_data[tmp_location] = {}
for j in range(2, 11):
# Cột các giải từ giải 8 đến giải đặc biệt
tmp_giai = data_resp.xpath("//table[@id='MN0']/tr[{0}]/td[1]/text()".format(j)).extract_first()
# Các số trúng thưởng trong cột theo tỉnh
tmp_number = data_resp.xpath("//table[@id='MN0']/tr[{0}]/td[{1}]//text()".format(j, i)).extract()
tmp_data[tmp_location][tmp_giai] = ", ".join(tmp_number)
xs_item['xs_data'] = tmp_data
yield xs_item
Đoạn code trong bài viết này sẽ lấy toàn bộ kết quả xổ số miền nam trong tháng 5 / 2018. Bạn có thể chạy thử và export ra file json như sau
scrapy crawl xosokienthiet -o items.json
Kết quả file json xuất ra:
[
{
"xs_info": [
"Th\u1ee9 3",
"01/05",
2018
],
"xs_data": {
"B\u1ea1c Li\u00eau": {
"G.8": "16",
"G.7": "353",
"G.6": "1283, 2497, 2084",
"G.5": "9561",
"G.4": "67934, 79609, 63270, 27150, 04251, 51261, 61775",
"G.3": "45793, 07406",
"G.2": "26212",
"G.1": "15768",
"\u0110B": "438860"
},
"B\u1ebfn Tre": {
"G.8": "15",
"G.7": "483",
"G.6": "0154, 8968, 3085",
"G.5": "5863",
"G.4": "17874, 34119, 64424, 88845, 68378, 11636, 93548",
"G.3": "20315, 31614",
"G.2": "41506",
"G.1": "05130",
"\u0110B": "681123"
},
"V\u0169ng T\u00e0u": {
"G.8": "86",
"G.7": "673",
"G.6": "7176, 1084, 3496",
"G.5": "0710",
"G.4": "51255, 57251, 41723, 97928, 71170, 78012, 22896",
"G.3": "65829, 98669",
"G.2": "94047",
"G.1": "51282",
"\u0110B": "822257"
}
}
},
{
"xs_info": [
"Th\u1ee9 6",
"04/05",
2018
],
"xs_data": {
"B\u00ecnh D\u01b0\u01a1ng": {
"G.8": "60",
"G.7": "452",
"G.6": "9257, 7863, 0383",
"G.5": "5972",
"G.4": "59619, 27706, 50746, 14303, 91998, 28277, 49387",
"G.3": "20633, 33908",
"G.2": "79568",
"G.1": "90491",
"\u0110B": "885468"
},
"Tr\u00e0 Vinh": {
"G.8": "38",
"G.7": "816",
"G.6": "4893, 4984, 5266",
"G.5": "5251",
"G.4": "16058, 86081, 49414, 36669, 85123, 24924, 33079",
"G.3": "51178, 49533",
"G.2": "42977",
"G.1": "67217",
"\u0110B": "923726"
},
"V\u0129nh Long": {
"G.8": "84",
"G.7": "713",
"G.6": "8785, 3400, 0110",
"G.5": "9740",
"G.4": "82151, 99334, 34642, 61157, 96000, 11589, 23801",
"G.3": "81525, 22977",
"G.2": "69329",
"G.1": "25485",
"\u0110B": "344846"
}
}
},
{
"xs_info": [
"CN",
"06/05",
2018
],
"xs_data": {
"\u0110\u00e0 L\u1ea1t": {
"G.8": "69",
"G.7": "105",
"G.6": "4878, 0887, 3578",
"G.5": "5121",
"G.4": "79478, 49198, 20002, 95410, 18068, 03992, 60777",
"G.3": "87406, 07032",
"G.2": "88076",
"G.1": "42492",
"\u0110B": "620989"
},
"Ki\u00ean Giang": {
"G.8": "14",
"G.7": "106",
"G.6": "3550, 9384, 9957",
"G.5": "1671",
"G.4": "31918, 70479, 27675, 59528, 10239, 78092, 21698",
"G.3": "38876, 19127",
"G.2": "65845",
"G.1": "31073",
"\u0110B": "949938"
},
"Ti\u1ec1n Giang": {
"G.8": "37",
"G.7": "386",
"G.6": "9605, 6995, 2270",
"G.5": "1684",
"G.4": "54380, 82874, 67586, 63497, 32057, 13779, 46003",
"G.3": "24278, 74885",
"G.2": "25270",
"G.1": "51333",
"\u0110B": "192854"
}
}
},
{
"xs_info": [
"Th\u1ee9 5",
"03/05",
2018
],
"xs_data": {
"An Giang": {
"G.8": "94",
"G.7": "794",
"G.6": "0187, 4573, 3878",
"G.5": "3312",
"G.4": "20138, 93334, 90095, 35491, 35696, 02050, 03079",
"G.3": "34572, 72987",
"G.2": "37368",
"G.1": "12953",
"\u0110B": "005462"
},
"B\u00ecnh Thu\u1eadn": {
"G.8": "27",
"G.7": "663",
"G.6": "3645, 3468, 2176",
"G.5": "7737",
"G.4": "62771, 04263, 36750, 69320, 62382, 73465, 65376",
"G.3": "59577, 32743",
"G.2": "52100",
"G.1": "47715",
"\u0110B": "824830"
},
"T\u00e2y Ninh": {
"G.8": "83",
"G.7": "767",
"G.6": "4239, 3652, 9645",
"G.5": "5423",
"G.4": "31471, 50394, 77260, 02009, 22903, 97308, 89899",
"G.3": "32127, 39143",
"G.2": "82382",
"G.1": "23176",
"\u0110B": "281533"
}
}
},
{
"xs_info": [
"Th\u1ee9 7",
"05/05",
2018
],
"xs_data": {
"B\u00ecnh Ph\u01b0\u1edbc": {
"G.8": "67",
"G.7": "965",
"G.6": "1695, 9928, 8916",
"G.5": "7285",
"G.4": "84710, 05606, 78237, 97939, 99657, 89430, 71291",
"G.3": "50955, 41193",
"G.2": "87111",
"G.1": "79999",
"\u0110B": "664905"
},
"TP.HCM": {
"G.8": "13",
"G.7": "763",
"G.6": "5735, 2650, 9395",
"G.5": "3853",
"G.4": "13106, 23340, 90176, 15614, 23642, 87545, 32097",
"G.3": "12392, 79917",
"G.2": "43408",
"G.1": "22796",
"\u0110B": "863955"
},
"H\u1eadu Giang": {
"G.8": "33",
"G.7": "088",
"G.6": "9982, 3416, 4420",
"G.5": "6240",
"G.4": "59187, 71216, 38613, 75620, 40299, 89214, 63035",
"G.3": "57508, 95761",
"G.2": "91377",
"G.1": "41359",
"\u0110B": "275874"
}
}
},
{
"xs_info": [
"Th\u1ee9 4",
"02/05",
2018
],
"xs_data": {
"C\u1ea7n Th\u01a1": {
"G.8": "29",
"G.7": "415",
"G.6": "4349, 3660, 7518",
"G.5": "0664",
"G.4": "57233, 18537, 63657, 80663, 98840, 11854, 96175",
"G.3": "52599, 17432",
"G.2": "60654",
"G.1": "65835",
"\u0110B": "404049"
},
"\u0110\u1ed3ng Nai": {
"G.8": "69",
"G.7": "741",
"G.6": "2933, 4759, 3205",
"G.5": "0888",
"G.4": "20376, 44093, 59339, 48904, 27532, 63456, 50913",
"G.3": "58367, 72465",
"G.2": "43852",
"G.1": "76663",
"\u0110B": "533867"
},
"S\u00f3c Tr\u0103ng": {
"G.8": "84",
"G.7": "654",
"G.6": "4998, 3841, 8098",
"G.5": "9041",
"G.4": "80284, 15544, 50263, 16830, 73421, 28479, 49643",
"G.3": "67012, 17594",
"G.2": "25363",
"G.1": "11726",
"\u0110B": "920992"
}
}
},
{
"xs_info": [
"Th\u1ee9 5",
"10/05",
2018
],
"xs_data": {
"An Giang": {
"G.8": "52",
"G.7": "932",
"G.6": "3623, 4593, 4384",
"G.5": "2262",
"G.4": "45457, 15597, 79475, 32808, 44451, 07640, 06155",
"G.3": "09383, 08366",
"G.2": "31879",
"G.1": "23741",
"\u0110B": "450580"
},
"B\u00ecnh Thu\u1eadn": {
"G.8": "65",
"G.7": "418",
"G.6": "0312, 9128, 3209",
"G.5": "1971",
"G.4": "47031, 34801, 63126, 75945, 39134, 06160, 57141",
"G.3": "75258, 12882",
"G.2": "38951",
"G.1": "29188",
"\u0110B": "172096"
},
"T\u00e2y Ninh": {
"G.8": "64",
"G.7": "688",
"G.6": "6407, 3101, 6357",
"G.5": "2315",
"G.4": "92331, 12204, 09469, 18618, 41193, 16730, 75205",
"G.3": "10671, 61843",
"G.2": "90852",
"G.1": "79720",
"\u0110B": "535419"
}
}
},
{
"xs_info": [
"CN",
"13/05",
2018
],
"xs_data": {
"\u0110\u00e0 L\u1ea1t": {
"G.8": "14",
"G.7": "724",
"G.6": "0981, 2263, 6944",
"G.5": "8656",
"G.4": "96994, 23915, 63782, 08057, 50918, 16647, 78389",
"G.3": "83976, 83047",
"G.2": "89079",
"G.1": "70743",
"\u0110B": "002603"
},
"Ki\u00ean Giang": {
"G.8": "83",
"G.7": "852",
"G.6": "3985, 1752, 0070",
"G.5": "6099",
"G.4": "19349, 08761, 65055, 53976, 78993, 80259, 53912",
"G.3": "67207, 24247",
"G.2": "25263",
"G.1": "59241",
"\u0110B": "335122"
},
"Ti\u1ec1n Giang": {
"G.8": "19",
"G.7": "696",
"G.6": "5313, 0922, 1814",
"G.5": "5018",
"G.4": "32428, 56233, 29224, 70849, 20669, 17458, 89764",
"G.3": "07611, 16460",
"G.2": "71609",
"G.1": "34096",
"\u0110B": "372540"
}
}
},
{
"xs_info": [
"Th\u1ee9 5",
"10/05",
2018
],
"xs_data": {
"An Giang": {
"G.8": "52",
"G.7": "932",
"G.6": "3623, 4593, 4384",
"G.5": "2262",
"G.4": "45457, 15597, 79475, 32808, 44451, 07640, 06155",
"G.3": "09383, 08366",
"G.2": "31879",
"G.1": "23741",
"\u0110B": "450580"
},
"B\u00ecnh Thu\u1eadn": {
"G.8": "65",
"G.7": "418",
"G.6": "0312, 9128, 3209",
"G.5": "1971",
"G.4": "47031, 34801, 63126, 75945, 39134, 06160, 57141",
"G.3": "75258, 12882",
"G.2": "38951",
"G.1": "29188",
"\u0110B": "172096"
},
"T\u00e2y Ninh": {
"G.8": "64",
"G.7": "688",
"G.6": "6407, 3101, 6357",
"G.5": "2315",
"G.4": "92331, 12204, 09469, 18618, 41193, 16730, 75205",
"G.3": "10671, 61843",
"G.2": "90852",
"G.1": "79720",
"\u0110B": "535419"
}
}
},
{
"xs_info": [
"Th\u1ee9 2",
"14/05",
2018
],
"xs_data": {
"C\u00e0 Mau": {
"G.8": "50",
"G.7": "062",
"G.6": "7829, 7241, 2292",
"G.5": "2879",
"G.4": "71148, 83336, 85846, 33476, 78844, 09520, 96175",
"G.3": "68542, 98264",
"G.2": "51031",
"G.1": "44839",
"\u0110B": "886930"
},
"\u0110\u1ed3ng Th\u00e1p": {
"G.8": "83",
"G.7": "687",
"G.6": "8322, 7707, 0439",
"G.5": "4953",
"G.4": "56354, 90245, 87152, 08383, 70004, 21246, 44655",
"G.3": "90339, 33914",
"G.2": "63369",
"G.1": "20810",
"\u0110B": "681146"
},
"TP.HCM": {
"G.8": "91",
"G.7": "832",
"G.6": "5246, 0202, 1223",
"G.5": "6334",
"G.4": "86302, 45657, 46403, 30653, 58588, 61869, 58876",
"G.3": "77792, 29748",
"G.2": "63626",
"G.1": "57976",
"\u0110B": "891481"
}
}
},
{
"xs_info": [
"Th\u1ee9 6",
"11/05",
2018
],
"xs_data": {
"B\u00ecnh D\u01b0\u01a1ng": {
"G.8": "00",
"G.7": "581",
"G.6": "9814, 2826, 3228",
"G.5": "1346",
"G.4": "55991, 73399, 79308, 32271, 61524, 13497, 99399",
"G.3": "52502, 05619",
"G.2": "84193",
"G.1": "79797",
"\u0110B": "027386"
},
"Tr\u00e0 Vinh": {
"G.8": "56",
"G.7": "409",
"G.6": "2533, 5208, 0365",
"G.5": "0001",
"G.4": "16617, 64534, 30356, 46688, 17038, 75826, 08697",
"G.3": "68794, 07939",
"G.2": "23420",
"G.1": "78858",
"\u0110B": "822105"
},
"V\u0129nh Long": {
"G.8": "85",
"G.7": "033",
"G.6": "3620, 1082, 1862",
"G.5": "3696",
"G.4": "26075, 88528, 64495, 11137, 64648, 67412, 46023",
"G.3": "12039, 44360",
"G.2": "46047",
"G.1": "81352",
"\u0110B": "895054"
}
}
},
{
"xs_info": [
"Th\u1ee9 3",
"15/05",
2018
],
"xs_data": {
"B\u1ea1c Li\u00eau": {
"G.8": "66",
"G.7": "000",
"G.6": "0090, 1091, 2879",
"G.5": "8770",
"G.4": "06751, 32335, 27980, 27472, 35808, 12066, 82838",
"G.3": "52210, 82044",
"G.2": "20959",
"G.1": "41630",
"\u0110B": "870719"
},
"B\u1ebfn Tre": {
"G.8": "19",
"G.7": "456",
"G.6": "0993, 8004, 3803",
"G.5": "9769",
"G.4": "03154, 19514, 54967, 00214, 50462, 20751, 18357",
"G.3": "81474, 44403",
"G.2": "29612",
"G.1": "44784",
"\u0110B": "712739"
},
"V\u0169ng T\u00e0u": {
"G.8": "98",
"G.7": "006",
"G.6": "1658, 8555, 9396",
"G.5": "7514",
"G.4": "52543, 35456, 18575, 17145, 64830, 31446, 24205",
"G.3": "57273, 42422",
"G.2": "83413",
"G.1": "32578",
"\u0110B": "067898"
}
}
},
{
"xs_info": [
"Th\u1ee9 7",
"12/05",
2018
],
"xs_data": {
"B\u00ecnh Ph\u01b0\u1edbc": {
"G.8": "70",
"G.7": "861",
"G.6": "2401, 3299, 1381",
"G.5": "5459",
"G.4": "65942, 07862, 08658, 95400, 44921, 86284, 85659",
"G.3": "05372, 72401",
"G.2": "30070",
"G.1": "50886",
"\u0110B": "260083"
},
"TP.HCM": {
"G.8": "44",
"G.7": "714",
"G.6": "4804, 7269, 6115",
"G.5": "4468",
"G.4": "15752, 91761, 14370, 01574, 10493, 60161, 35972",
"G.3": "28954, 61737",
"G.2": "06914",
"G.1": "77743",
"\u0110B": "063815"
},
"H\u1eadu Giang": {
"G.8": "51",
"G.7": "149",
"G.6": "6513, 1728, 3611",
"G.5": "9673",
"G.4": "08006, 64012, 96163, 31589, 02607, 83270, 86758",
"G.3": "90875, 65820",
"G.2": "95155",
"G.1": "30506",
"\u0110B": "377118"
}
}
},
{
"xs_info": [
"Th\u1ee9 4",
"16/05",
2018
],
"xs_data": {
"C\u1ea7n Th\u01a1": {
"G.8": "40",
"G.7": "544",
"G.6": "1768, 2173, 2902",
"G.5": "5969",
"G.4": "18672, 39484, 98138, 31078, 61683, 76635, 92603",
"G.3": "06110, 91619",
"G.2": "06506",
"G.1": "29596",
"\u0110B": "815161"
},
"\u0110\u1ed3ng Nai": {
"G.8": "85",
"G.7": "467",
"G.6": "3413, 0425, 7125",
"G.5": "3939",
"G.4": "91987, 06549, 46514, 30528, 08769, 98142, 27266",
"G.3": "74485, 78765",
"G.2": "79011",
"G.1": "30890",
"\u0110B": "719280"
},
"S\u00f3c Tr\u0103ng": {
"G.8": "65",
"G.7": "792",
"G.6": "2213, 7877, 9988",
"G.5": "5595",
"G.4": "50098, 05036, 29895, 43900, 72992, 41950, 69852",
"G.3": "46641, 37440",
"G.2": "58106",
"G.1": "80428",
"\u0110B": "588943"
}
}
},
{
"xs_info": [
"Th\u1ee9 5",
"17/05",
2018
],
"xs_data": {
"An Giang": {
"G.8": "74",
"G.7": "869",
"G.6": "1044, 7984, 2942",
"G.5": "7802",
"G.4": "47435, 82120, 74793, 58931, 38300, 68963, 42988",
"G.3": "91186, 99520",
"G.2": "32990",
"G.1": "04955",
"\u0110B": "046984"
},
"B\u00ecnh Thu\u1eadn": {
"G.8": "57",
"G.7": "153",
"G.6": "2010, 6583, 1173",
"G.5": "0059",
"G.4": "49118, 93962, 39111, 43927, 64837, 42950, 92552",
"G.3": "33427, 15263",
"G.2": "11703",
"G.1": "39283",
"\u0110B": "641919"
},
"T\u00e2y Ninh": {
"G.8": "88",
"G.7": "967",
"G.6": "3518, 0591, 6093",
"G.5": "3379",
"G.4": "69375, 10092, 59277, 86682, 56008, 38743, 96116",
"G.3": "23103, 72148",
"G.2": "31074",
"G.1": "27535",
"\u0110B": "268378"
}
}
},
{
"xs_info": [
"Th\u1ee9 6",
"18/05",
2018
],
"xs_data": {
"B\u00ecnh D\u01b0\u01a1ng": {
"G.8": "45",
"G.7": "454",
"G.6": "9434, 5294, 7199",
"G.5": "6113",
"G.4": "76230, 15907, 91024, 16331, 20848, 39279, 43377",
"G.3": "37186, 13053",
"G.2": "97007",
"G.1": "15801",
"\u0110B": "338337"
},
"Tr\u00e0 Vinh": {
"G.8": "59",
"G.7": "965",
"G.6": "3226, 3244, 3813",
"G.5": "5866",
"G.4": "42235, 40800, 96581, 15130, 46169, 44271, 26175",
"G.3": "89387, 72525",
"G.2": "11408",
"G.1": "20797",
"\u0110B": "820545"
},
"V\u0129nh Long": {
"G.8": "36",
"G.7": "165",
"G.6": "4776, 4761, 1075",
"G.5": "8955",
"G.4": "33667, 88817, 12891, 10869, 53596, 73419, 43164",
"G.3": "70861, 88032",
"G.2": "94950",
"G.1": "37427",
"\u0110B": "014217"
}
}
},
{
"xs_info": [
"CN",
"20/05",
2018
],
"xs_data": {
"\u0110\u00e0 L\u1ea1t": {
"G.8": "72",
"G.7": "039",
"G.6": "9979, 1767, 4766",
"G.5": "3537",
"G.4": "44987, 74228, 96852, 83325, 94751, 67100, 05293",
"G.3": "91699, 31240",
"G.2": "48851",
"G.1": "43269",
"\u0110B": "044063"
},
"Ki\u00ean Giang": {
"G.8": "34",
"G.7": "861",
"G.6": "4819, 5443, 2039",
"G.5": "2015",
"G.4": "26106, 80759, 53526, 19180, 44852, 94250, 21065",
"G.3": "28094, 23312",
"G.2": "16303",
"G.1": "66229",
"\u0110B": "056954"
},
"Ti\u1ec1n Giang": {
"G.8": "05",
"G.7": "058",
"G.6": "7060, 8984, 3634",
"G.5": "6068",
"G.4": "23283, 63168, 13983, 12925, 97812, 10431, 81082",
"G.3": "88846, 95940",
"G.2": "07232",
"G.1": "81944",
"\u0110B": "104825"
}
}
},
{
"xs_info": [
"Th\u1ee9 7",
"19/05",
2018
],
"xs_data": {
"B\u00ecnh Ph\u01b0\u1edbc": {
"G.8": "73",
"G.7": "543",
"G.6": "2792, 7334, 7512",
"G.5": "1333",
"G.4": "73979, 68517, 13135, 65355, 44527, 87510, 40813",
"G.3": "95763, 39098",
"G.2": "40793",
"G.1": "62785",
"\u0110B": "055443"
},
"TP.HCM": {
"G.8": "17",
"G.7": "732",
"G.6": "8526, 7505, 4115",
"G.5": "3353",
"G.4": "57730, 80757, 89799, 88783, 91112, 63303, 07912",
"G.3": "63236, 90396",
"G.2": "85013",
"G.1": "94177",
"\u0110B": "516387"
},
"H\u1eadu Giang": {
"G.8": "66",
"G.7": "048",
"G.6": "1624, 0900, 0505",
"G.5": "4476",
"G.4": "23027, 41434, 18215, 30378, 15191, 17212, 80807",
"G.3": "14303, 14958",
"G.2": "95601",
"G.1": "65749",
"\u0110B": "806861"
}
}
},
{
"xs_info": [
"Th\u1ee9 3",
"22/05",
2018
],
"xs_data": {
"B\u1ea1c Li\u00eau": {
"G.8": "39",
"G.7": "357",
"G.6": "5218, 3191, 7013",
"G.5": "4813",
"G.4": "38567, 43365, 52398, 18351, 58634, 61965, 54313",
"G.3": "72461, 18327",
"G.2": "44504",
"G.1": "08742",
"\u0110B": "946382"
},
"B\u1ebfn Tre": {
"G.8": "90",
"G.7": "583",
"G.6": "6649, 5307, 9536",
"G.5": "8653",
"G.4": "80349, 89569, 94674, 29193, 59650, 34183, 96613",
"G.3": "68333, 96747",
"G.2": "55911",
"G.1": "93965",
"\u0110B": "835548"
},
"V\u0169ng T\u00e0u": {
"G.8": "44",
"G.7": "505",
"G.6": "9521, 1149, 7662",
"G.5": "1167",
"G.4": "79007, 63331, 34122, 78615, 84404, 59515, 60905",
"G.3": "00481, 77479",
"G.2": "39346",
"G.1": "01123",
"\u0110B": "785018"
}
}
},
{
"xs_info": [
"Th\u1ee9 2",
"21/05",
2018
],
"xs_data": {
"C\u00e0 Mau": {
"G.8": "36",
"G.7": "759",
"G.6": "9940, 3566, 1586",
"G.5": "7621",
"G.4": "41671, 47806, 76284, 88755, 96178, 80638, 37923",
"G.3": "67670, 49788",
"G.2": "98617",
"G.1": "85543",
"\u0110B": "496531"
},
"\u0110\u1ed3ng Th\u00e1p": {
"G.8": "04",
"G.7": "919",
"G.6": "2265, 8000, 2095",
"G.5": "5631",
"G.4": "49618, 15768, 54250, 93495, 65639, 81435, 68721",
"G.3": "60252, 26651",
"G.2": "80621",
"G.1": "79590",
"\u0110B": "955252"
},
"TP.HCM": {
"G.8": "67",
"G.7": "681",
"G.6": "8465, 7091, 5032",
"G.5": "6329",
"G.4": "84819, 58924, 38198, 63449, 26315, 75972, 30626",
"G.3": "79670, 00612",
"G.2": "00903",
"G.1": "96365",
"\u0110B": "058352"
}
}
},
{
"xs_info": [
"Th\u1ee9 7",
"26/05",
2018
],
"xs_data": {
"B\u00ecnh Ph\u01b0\u1edbc": {
"G.8": "20",
"G.7": "878",
"G.6": "6687, 0387, 5796",
"G.5": "7882",
"G.4": "39378, 43576, 87635, 00406, 60658, 71665, 83310",
"G.3": "00111, 06782",
"G.2": "90474",
"G.1": "52522",
"\u0110B": "907183"
},
"TP.HCM": {
"G.8": "54",
"G.7": "951",
"G.6": "4015, 5744, 1451",
"G.5": "6098",
"G.4": "51848, 20493, 59247, 76987, 96192, 83293, 94301",
"G.3": "21853, 47038",
"G.2": "24064",
"G.1": "66049",
"\u0110B": "122345"
},
"H\u1eadu Giang": {
"G.8": "20",
"G.7": "792",
"G.6": "1923, 1621, 3319",
"G.5": "9753",
"G.4": "76528, 64769, 44012, 77147, 28947, 65805, 18806",
"G.3": "49068, 23065",
"G.2": "15731",
"G.1": "69743",
"\u0110B": "820456"
}
}
},
{
"xs_info": [
"CN",
"27/05",
2018
],
"xs_data": {
"\u0110\u00e0 L\u1ea1t": {
"G.8": "69",
"G.7": "982",
"G.6": "9851, 9642, 9521",
"G.5": "7972",
"G.4": "31215, 82451, 99299, 86296, 09659, 83301, 42201",
"G.3": "99146, 24034",
"G.2": "16114",
"G.1": "46406",
"\u0110B": "014287"
},
"Ki\u00ean Giang": {
"G.8": "10",
"G.7": "447",
"G.6": "1603, 3796, 1095",
"G.5": "9918",
"G.4": "65947, 11195, 49669, 87857, 27333, 48558, 42031",
"G.3": "24349, 48603",
"G.2": "24341",
"G.1": "16086",
"\u0110B": "179516"
},
"Ti\u1ec1n Giang": {
"G.8": "53",
"G.7": "997",
"G.6": "2357, 4759, 5377",
"G.5": "1624",
"G.4": "89160, 68442, 72256, 14522, 73416, 52382, 12042",
"G.3": "97760, 51079",
"G.2": "33967",
"G.1": "46245",
"\u0110B": "799397"
}
}
},
{
"xs_info": [
"Th\u1ee9 5",
"24/05",
2018
],
"xs_data": {
"An Giang": {
"G.8": "69",
"G.7": "665",
"G.6": "5140, 3308, 1360",
"G.5": "0271",
"G.4": "27734, 70204, 36634, 24802, 69670, 29777, 57372",
"G.3": "27754, 02149",
"G.2": "93033",
"G.1": "43389",
"\u0110B": "245787"
},
"B\u00ecnh Thu\u1eadn": {
"G.8": "71",
"G.7": "100",
"G.6": "4348, 9392, 3964",
"G.5": "6157",
"G.4": "88682, 49218, 45941, 16929, 34583, 57601, 15960",
"G.3": "85513, 05662",
"G.2": "72926",
"G.1": "35416",
"\u0110B": "158020"
},
"T\u00e2y Ninh": {
"G.8": "60",
"G.7": "586",
"G.6": "8908, 6583, 8954",
"G.5": "3702",
"G.4": "15934, 29619, 04654, 96746, 41170, 98994, 89288",
"G.3": "38847, 18065",
"G.2": "47429",
"G.1": "85282",
"\u0110B": "598291"
}
}
},
{
"xs_info": [
"Th\u1ee9 5",
"24/05",
2018
],
"xs_data": {
"An Giang": {
"G.8": "69",
"G.7": "665",
"G.6": "5140, 3308, 1360",
"G.5": "0271",
"G.4": "27734, 70204, 36634, 24802, 69670, 29777, 57372",
"G.3": "27754, 02149",
"G.2": "93033",
"G.1": "43389",
"\u0110B": "245787"
},
"B\u00ecnh Thu\u1eadn": {
"G.8": "71",
"G.7": "100",
"G.6": "4348, 9392, 3964",
"G.5": "6157",
"G.4": "88682, 49218, 45941, 16929, 34583, 57601, 15960",
"G.3": "85513, 05662",
"G.2": "72926",
"G.1": "35416",
"\u0110B": "158020"
},
"T\u00e2y Ninh": {
"G.8": "60",
"G.7": "586",
"G.6": "8908, 6583, 8954",
"G.5": "3702",
"G.4": "15934, 29619, 04654, 96746, 41170, 98994, 89288",
"G.3": "38847, 18065",
"G.2": "47429",
"G.1": "85282",
"\u0110B": "598291"
}
}
},
{
"xs_info": [
"Th\u1ee9 6",
"25/05",
2018
],
"xs_data": {
"B\u00ecnh D\u01b0\u01a1ng": {
"G.8": "01",
"G.7": "968",
"G.6": "7425, 2535, 0782",
"G.5": "6232",
"G.4": "69076, 95402, 96005, 80486, 54500, 28140, 65060",
"G.3": "71574, 29344",
"G.2": "20571",
"G.1": "03635",
"\u0110B": "610660"
},
"Tr\u00e0 Vinh": {
"G.8": "15",
"G.7": "024",
"G.6": "6133, 9816, 4274",
"G.5": "8228",
"G.4": "15207, 38079, 95421, 44928, 39125, 01437, 74905",
"G.3": "03808, 43454",
"G.2": "54319",
"G.1": "27914",
"\u0110B": "277784"
},
"V\u0129nh Long": {
"G.8": "07",
"G.7": "750",
"G.6": "3780, 7858, 3640",
"G.5": "5939",
"G.4": "66763, 80974, 89550, 80172, 61695, 95040, 80192",
"G.3": "11263, 58077",
"G.2": "10917",
"G.1": "94594",
"\u0110B": "934328"
}
}
},
{
"xs_info": [
"Th\u1ee9 4",
"23/05",
2018
],
"xs_data": {
"C\u1ea7n Th\u01a1": {
"G.8": "29",
"G.7": "482",
"G.6": "9867, 9416, 2625",
"G.5": "3654",
"G.4": "88757, 83187, 37175, 86074, 76987, 30384, 07811",
"G.3": "05749, 97268",
"G.2": "29494",
"G.1": "17878",
"\u0110B": "811998"
},
"\u0110\u1ed3ng Nai": {
"G.8": "13",
"G.7": "770",
"G.6": "1227, 5479, 7059",
"G.5": "0749",
"G.4": "40644, 78756, 60762, 34042, 31113, 72578, 70204",
"G.3": "11922, 40869",
"G.2": "29119",
"G.1": "89808",
"\u0110B": "895992"
},
"S\u00f3c Tr\u0103ng": {
"G.8": "95",
"G.7": "480",
"G.6": "4678, 1568, 4840",
"G.5": "8792",
"G.4": "88753, 41858, 10187, 63942, 35530, 04361, 93835",
"G.3": "57902, 66294",
"G.2": "32106",
"G.1": "65544",
"\u0110B": "010629"
}
}
},
{
"xs_info": [
"Th\u1ee9 6",
"25/05",
2018
],
"xs_data": {
"B\u00ecnh D\u01b0\u01a1ng": {
"G.8": "01",
"G.7": "968",
"G.6": "7425, 2535, 0782",
"G.5": "6232",
"G.4": "69076, 95402, 96005, 80486, 54500, 28140, 65060",
"G.3": "71574, 29344",
"G.2": "20571",
"G.1": "03635",
"\u0110B": "610660"
},
"Tr\u00e0 Vinh": {
"G.8": "15",
"G.7": "024",
"G.6": "6133, 9816, 4274",
"G.5": "8228",
"G.4": "15207, 38079, 95421, 44928, 39125, 01437, 74905",
"G.3": "03808, 43454",
"G.2": "54319",
"G.1": "27914",
"\u0110B": "277784"
},
"V\u0129nh Long": {
"G.8": "07",
"G.7": "750",
"G.6": "3780, 7858, 3640",
"G.5": "5939",
"G.4": "66763, 80974, 89550, 80172, 61695, 95040, 80192",
"G.3": "11263, 58077",
"G.2": "10917",
"G.1": "94594",
"\u0110B": "934328"
}
}
},
{
"xs_info": [
"Th\u1ee9 4",
"30/05",
2018
],
"xs_data": {
"C\u1ea7n Th\u01a1": {
"G.8": "75",
"G.7": "039",
"G.6": "7177, 9837, 3440",
"G.5": "5498",
"G.4": "20745, 43337, 83306, 45019, 25140, 46648, 81118",
"G.3": "61182, 01711",
"G.2": "35737",
"G.1": "93596",
"\u0110B": "167473"
},
"\u0110\u1ed3ng Nai": {
"G.8": "60",
"G.7": "278",
"G.6": "2268, 8312, 2377",
"G.5": "1802",
"G.4": "53848, 56462, 98202, 57696, 69935, 87180, 82637",
"G.3": "59868, 27844",
"G.2": "84448",
"G.1": "25309",
"\u0110B": "580647"
},
"S\u00f3c Tr\u0103ng": {
"G.8": "52",
"G.7": "715",
"G.6": "8793, 8260, 8794",
"G.5": "1216",
"G.4": "05305, 57986, 16308, 23942, 71828, 95079, 88159",
"G.3": "79918, 65304",
"G.2": "64523",
"G.1": "53567",
"\u0110B": "761141"
}
}
},
{
"xs_info": [
"Th\u1ee9 2",
"07/05",
2018
],
"xs_data": {
"C\u00e0 Mau": {
"G.8": "94",
"G.7": "652",
"G.6": "2907, 2337, 5948",
"G.5": "8170",
"G.4": "13885, 56888, 58359, 89414, 98428, 00378, 53725",
"G.3": "08025, 47033",
"G.2": "69301",
"G.1": "46213",
"\u0110B": "895478"
},
"\u0110\u1ed3ng Th\u00e1p": {
"G.8": "80",
"G.7": "504",
"G.6": "5777, 8074, 8228",
"G.5": "0699",
"G.4": "29682, 28851, 07260, 91185, 51636, 94494, 65145",
"G.3": "28169, 32168",
"G.2": "55596",
"G.1": "05483",
"\u0110B": "493447"
},
"TP.HCM": {
"G.8": "62",
"G.7": "251",
"G.6": "4067, 4810, 7087",
"G.5": "3912",
"G.4": "86233, 53989, 93622, 34544, 23840, 18770, 70994",
"G.3": "33598, 09021",
"G.2": "14893",
"G.1": "12096",
"\u0110B": "236959"
}
}
},
{
"xs_info": [
"Th\u1ee9 3",
"08/05",
2018
],
"xs_data": {
"B\u1ea1c Li\u00eau": {
"G.8": "44",
"G.7": "488",
"G.6": "3643, 9439, 4043",
"G.5": "1597",
"G.4": "41892, 86239, 46011, 25661, 87280, 38105, 27863",
"G.3": "16120, 29956",
"G.2": "04732",
"G.1": "85851",
"\u0110B": "921072"
},
"B\u1ebfn Tre": {
"G.8": "04",
"G.7": "236",
"G.6": "3071, 1354, 0910",
"G.5": "3234",
"G.4": "76649, 60435, 31076, 97175, 08419, 65465, 38763",
"G.3": "78410, 77712",
"G.2": "60082",
"G.1": "21332",
"\u0110B": "348921"
},
"V\u0169ng T\u00e0u": {
"G.8": "33",
"G.7": "190",
"G.6": "9517, 1422, 0304",
"G.5": "2155",
"G.4": "17700, 20398, 89251, 41507, 77627, 69396, 38502",
"G.3": "03188, 66896",
"G.2": "28589",
"G.1": "96082",
"\u0110B": "493208"
}
}
}
]
Nếu bạn muốn lưu kết quả vào database, bạn phải kích hoạt pipeline. Mình sẽ dùng sqlite3 trong ví dụ này. Bạn mở file settings.py vào tìm ITEM_PIPELINE ra và uncomment
ITEM_PIPELINES = {
'xskt.pipelines.XsktPipeline': 300,
}
Bây giờ bạn hãy mở file pipelines.py và chỉnh sửa như sau
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
from sqlite3 import dbapi2 as sqlite
class XsktPipeline(object):
def __init__(self):
self.connection = sqlite.connect('./xs_database.db')
self.cursor = self.connection.cursor()
self.cursor.execute('CREATE TABLE IF NOT EXISTS kq_xs '
'(id INTEGER PRIMARY KEY, xs_thu VARCHAR(80),'
'xs_ngay_thang VARCHAR(80), xs_nam VARCHAR(80), xs_data TEXT)')
def process_item(self, item, spider):
self.cursor.execute("select * from kq_xs where xs_thu=? and xs_ngay_thang=? and xs_nam=?", (item['xs_info'][0], item['xs_info'][1], item['xs_info'][2]))
result = self.cursor.fetchone()
if not result:
self.cursor.execute(
"insert into kq_xs (xs_thu, xs_ngay_thang, xs_nam, xs_data) values (?, ?, ?, ?)",
(item['xs_info'][0], item['xs_info'][1], item['xs_info'][2], str(item['xs_data'])))
self.connection.commit()
return item
Sau đó bạn chạy command
scrapy crawl xosokienthiet
Kết quả sau khi chạy scrapy
Hướng dẫn phân tích site để lấy xpath
Đầu tiên ta cần vào site lấy dữ liệu http://xskt.com.vn/ket-qua-xo-so-theo-ngay/mien-nam-xsmn/01-6-2018.html
Để lấy thứ ta cần biết là table chứa bảng số này có class hay id gì khác biệt không. Bạn hãy dùng Inspector (nhấn F12 hoặc click phải lên Thứ 6) để xem
Theo hình trên table này có cả Id và class để chúng ta khai thác. Nhưng vì class sẽ có thể dễ bị trùng với các element khác, nên chúng ta sẽ sử dụng id. Bạn hãy ghi lại MN0.
Tiếp theo ta sẽ xem tới "Thứ 6", ta thấy "Thứ 6" nằm trong table (id = MN0) > tr > th[1] > a (text). th[1] chỉ định th đầu tiên trong table
data_resp.xpath("//table[@id='MN0']/tr/th[1]/a/text()").extract_first()
Tương tự cho ngày tháng sẽ là table (id = MN0) > tr > th[1] (text)
data_resp.xpath("//table[@id='MN0']/tr/th[1]/text()").extract_first()
Các element khác bạn cũng làm tương tự như vậy. Bạn hãy thử tự phân tích xem sao.
Bài viết hướng dẫn scrapy - công cụ bóc tách dữ đến đây là kết thúc. Mọi ý kiến góp ý của các bạn mình rất hoan nghênh. Các bạn thắc mắc có thể hỏi mình bằng cách comment tại bài viết này hoặc trên group Python Community Viet Nam. Chúc các bạn tự học python thành công.
Link github: https://github.com/kikyo2006/scrapy-demo-xskt
hai nam ngo
scrapy mình cài bị lỗi : Could not install packages due to an EnvironmentError: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/queuelib-1.5.0.dist-info'
Consider using the `--user` option or check the permissions.
admin có cách nào khắc phục không
Anh Vũ Từ
Chào bạn, hình như bạn đang cài scrapy trực tiếp vào system.
Bạn thử với command: sudo pip install scrapy
để cài đặt scrapy với quyền admin, hoặc bạn có thể tạo virtualenv để cài đặt với command:
pip install scrapy
Trần Cương
Một fan của python. Rất rất cảm ơn anh đã tạo ra một trang web rất bổ ích. Mong anh ra nhiều bài hay nữa nhé.
To Cun
Ad cho mình hỏi Khi chạy lệnh scrapy crawl xosokienthiet -o items.json thì bị lỗi
KeyError: 'XsktItem does not support field: xs_info'
Lỗi này là bị làm sao ah?
Anh Vũ Từ
Chào bạn, bạn đã tạo các field cho XsktItem chưa?
class XsktItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
sx_info = scrapy.Field()
sx_data = scrapy.Field()
Nguyễn Trần Tuấn Anh
sx_info = scrapy.Field()
sx_data = scrapy.Field()
Sửa thành
xs_info = scrapy.Field()
xs_data = scrapy.Field()
nha
Anh Vũ Từ
Cám ơn bạn đã nhắc, lỗi do mình type lại khi viết bài chứ không copy, trên source github vẫn đúng. Mình đã cập nhật lại bài
Tai Pham
Mình đã tạo các field cho XsktItem rồi, nhưng khi chạy lệnh
scrapy crawl xosokienthiet -o items.json
vẫn bị lỗi ấy, mong ad giúp mình với
2019-01-22 11:38:51 [scrapy.core.scraper] ERROR: Spider error processing <GET https://xskt.com.vn/ket-qua-xo-so-theo-ngay/mien-nam-xsmn/29-5-2018.html> (referer: None)
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/scrapy/utils/defer.py", line 102, in iter_errback
yield next(it)
File "/usr/local/lib/python3.7/site-packages/scrapy/spidermiddlewares/offsite.py", line 30, in process_spider_output
for x in result:
File "/usr/local/lib/python3.7/site-packages/scrapy/spidermiddlewares/referer.py", line 339, in <genexpr>
return (_set_referer(r) for r in result or ())
File "/usr/local/lib/python3.7/site-packages/scrapy/spidermiddlewares/urllength.py", line 37, in <genexpr>
return (r for r in result or () if _filter(r))
File "/usr/local/lib/python3.7/site-packages/scrapy/spidermiddlewares/depth.py", line 58, in <genexpr>
return (r for r in result or () if _filter(r))
File "/Users/taipham/xskt/xskt/spiders/xosokienthiet.py", line 41, in parse
self.year_to_scrap
File "/usr/local/lib/python3.7/site-packages/scrapy/item.py", line 66, in __setitem__
(self.__class__.__name__, key))
KeyError: 'XsktItem does not support field: xs_info'
Anh Vũ Từ
Có thể do bạn đang dùng python 3.7, bạn downgrade xuống 3.6 test lại nha.
Anh Vũ Từ
Do mình đánh sai khi viết bài bạn sửa lại theo cách của bạn Nguyễn Trần Tuấn Anh nha
Bạn mở file items.py lên và sửa như sau:
sx_info = scrapy.Field()
sx_data = scrapy.Field()
Sửa thành
xs_info = scrapy.Field()
xs_data = scrapy.Field()
Nam
Anh ơi, file items.py có phải là xs_info và xs_data phải không ạ?
Kien
nhờ anh giúp xem lỗi này đang xài python 3.7.2 trên visual studio code
scrapy startproject xskt
scrapy : The term 'scrapy' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again.
At line:1 char:1
+ scrapy startproject xskt
+ ~~~~~~
+ CategoryInfo : ObjectNotFound: (scrapy:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Anh Vũ Từ
em check thử xem python đã được add vào environment path chưa
Anything
Unknown command : crawl sửa thế nào anh ạ